1. 程式人生 > >用java程式碼構建一棵平衡二杈樹:

用java程式碼構建一棵平衡二杈樹:

用java程式碼構建一棵平衡二杈樹:

構建的要點在於:
1. 每新增一個節點要遞迴地返回所有經過的父節點(要算好高度)
2. 計算每個節點的左右樹高度差
3. 如果高度差為2,認清要做哪種旋轉:LL, LR, RR, RL
4. 做旋轉時注意,所要移動節點之間的關係

程式碼如下:

package com.yjh.java.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class AVLTree {

    Note root = new
Note(); void add(Note root, Note note, AVLTree avlTree) { root.add(root, note, avlTree); } //用非遞迴方法列印樹(程式碼有點問題) void printf() { //將節點存入一個list中,得到一個排序好的集合(對排序樹遍歷) List<Note> list = new ArrayList<Note>(); Stack<Note> stack = new Stack<Note>(); //先取樹的根節點
Note note = this.root; do { //入棧 stack.push(note); //如果節點存在左孩子,則繼續入棧 if (note.lchild != null) { note = note.lchild; } //出棧 else { while (true) { note = stack.pop(); list
.add(note); if (null != note.rchild) { note = note.rchild; break; } } } } while (stack.size() != 0 || note.rchild != null); for (Note n : list) { System.out.println(n.data); } } public static void main(String[] args) { AVLTree tree = new AVLTree(); int arr[] = {5,8,9,3,6,7, 11, 10}; for (int i = 0; i < arr.length; i++) { tree.add(tree.root, new Note(arr[i]), tree); } tree.printf(); } } //定義節點 class Note { Integer data; Note parent; Note lchild; Note rchild; int height; public Note(int data) { this.data = data; } public Note() { } int getHeight(Note note) { return null == note ? -1 : note.height; } Note LR(Note note, AVLTree avlTree) { return LL(RR(note.lchild, avlTree).parent, avlTree); } Note LL(Note note, AVLTree avlTree) { Note parent = note.parent; Note lchild = note.lchild; if (parent == null) { avlTree.root = lchild; lchild.parent = null; } else { if (parent.data > lchild.data) { parent.lchild = lchild; }else { parent.rchild = lchild; } lchild.parent = parent; } if (lchild.rchild == null) { note.lchild = null; } else { note.lchild = note.lchild.rchild; note.lchild.parent = note; } note.parent = lchild; lchild.rchild = note; note.height = Math.max(getHeight(note.lchild), getHeight(note.rchild)) + 1; note.parent.height = Math.max(getHeight(note.parent.lchild), getHeight(note.parent.rchild)) + 1; return note.parent; } Note RL(Note note, AVLTree avlTree) { return RR(LL(note.rchild, avlTree).parent, avlTree); } Note RR(Note note, AVLTree avlTree) { Note parent = note.parent; Note rchild = note.rchild; if (parent == null) { avlTree.root = rchild; rchild.parent = null; } else { if (parent.data < rchild.data) { parent.rchild = rchild; } else { parent.lchild = rchild; } rchild.parent = parent; } if (rchild.lchild == null) { note.rchild = null; } else { note.rchild = note.rchild.lchild; note.rchild.parent = note; } note.parent = rchild; rchild.lchild = note; note.height = Math.max(getHeight(note.lchild), getHeight(note.rchild)) + 1; note.parent.height = Math.max(getHeight(note.parent.lchild), getHeight(note.parent.rchild)) + 1; return note.parent; } Note add(Note parent, Note newNote, AVLTree avlTree) { if (null != parent && null == parent.data) { parent.data = newNote.data; return parent; } //小於parent值往左新增 if (newNote.data < parent.data) { if (parent.lchild == null) { parent.lchild = newNote; newNote.parent = parent; } else { add(parent.lchild, newNote, avlTree); //檢查parent節點是否平衡 if (getHeight(parent.lchild) - getHeight(parent.rchild) == 2) { //LL if (parent.lchild.data > newNote.data) { LL(parent, avlTree); } //LR else { LR(parent, avlTree); } } } } //大於paren值往右新增 else { if (parent.rchild == null) { parent.rchild = newNote; newNote.parent = parent; } else { add(parent.rchild, newNote, avlTree); //檢查parent節點是否平衡 if (getHeight(parent.rchild) - getHeight(parent.lchild) == 2) { //RR if (parent.rchild.data < newNote.data) { RR(parent, avlTree); } //RL else { RL(parent, avlTree); } } } } //返回前先計算一下parent的高 parent.height = Math.max(getHeight(parent.lchild), getHeight(parent.rchild)) + 1; // 遞迴返回每個經過的節點 return parent; // } }