These two days finally the AVL tree to understand the next, in the "Algorithm Analysis and Design basics" This book, is arranged in the section of the transformation of law, is an example of simplifying the idea in the search tree application. The balance requirement is that the height difference between the left and right subtrees of each node does not exceed 1. So we just have to keep this balance when inserting or deleting nodes. If the balance is broken, use a series of rotations to bring the tree back to equilibrium.
There are a total of four types of rotation: Left single turn, right single turn, left and right double turn, left double turn. As long as the algorithmic Book of the AVL tree will have a rotating interpretation. Two single-turn, two-double-turn symmetry between the two. Seemingly complex double-turn, the idea is first converted into a single turn, so that the single-turn to achieve rebalancing. So the implementation of the four rotations can be very concise.
Because each rotation, we can restore the height of the tree to the level before insertion, so when the balance is broken, just one rotation is enough to solve the problem. And the need to rotate is the insertion node is located, the left and right sub-tree height difference is greater than 1 of the kid Tree.
Since the AVL tree is a balanced lookup tree, it is easier to remember from the normal two-fork lookup tree.
Binary tree insertion is performed recursively, which can express the idea of the algorithm very clearly. It is important to note that pointers are not available in the Java implementation, resulting in a need to be aware of hooking the inserted nodes to the original tree compared to C + +.
PUBLIC&NBSP;CLASS&NBSP;BINARYSORTTREE&NBSP;{//node Structure public static class binarytreenode{int v , height; Binarytreenode leftchild,rightchild;public binarytreenode (INT&NBSP;V) {this.v = v; this.leftchild = null;this.rightchild = null;this.height = 0;} Public binarytreenode (Int v, binarytreenode leftchild,binarytreenode rightchild,int height) {super (); this.v = v;this.leftchild = leftchild;this.rightchild = rightchild;this.height = height;}} Empty nodes need to be processed for -1public static int height (binarytreenode node) {return node == null ? -1:node.height;} Private binarytreenode root;public binarytreenode getroot () {return root;} Public void insert (int value) {This.root = insert (value,this.root);} Recursive insertion of Public binarytreenode insert (int value,binarytreenode t{if (t == null) {Return new binarytreenode (value);} The insertion value is compared to the current node, less than the insert to the left subtree, greater than the insert to right subtree if (VALUE&NBSP;<&NBSP;T.V) {T.leftchild = insert (value,t.leftchild);} Else if (VALUE&NBSP;>&NBSP;T.V) {T.rightchild = insert (value,t.rightchild);} else{/*equal,do nothing*/}//Update height T.height = math.max (height (t.leftchild), height ( T.rightchild)) + 1;return t;}}
The
has this foundation, and then the balance is achieved. The work required is to achieve 4 rotation, and override the insertion method, which, when inserted, rotates and restores balance if the balance is broken.
public class avltree extends binarysorttree{public binarytreenode Rotatewithleftchild (BINARYTREENODE&NBSP;K2) {binarytreenode k1 = k2.leftchild;k2.leftchild= k1.rightchild;k1.rightchild = k2;//Recalculate Height K2.height = math.max (height (k2.leftChild), Height (k2.rightchild)) + 1;k1.height = math.max (height (k1.leftchild), k2.height) &NBSP;+1;RETURN&NBSP;K1;} Public binarytreenode rotatewithrightchild (BINARYTREENODE&NBSP;K2) {binarytreenode k1 = k2.rightchild;k2.rightchild= k1.leftchild;k1.leftchild = k2;//Recalculate Height k2.height = math.max (height (k2.leftchild), height (k2.rightchild)) + 1;k1.height = math.max (height (K1.rightchild), k2.height) +1;return k1;} Public binarytreenode doublewithleftchild (BINARYTREENODE&NBSP;K3) {k3.leftchild = Rotatewithrightchild (K3.leftchild); Return rotatewithleftchild (K3);} Public&nbSp Binarytreenode doublewithrightchild (BINARYTREENODE&NBSP;K3) {K3.rightchild = rotatewithleftchild (K3.rightchild); Return rotatewithrightchild (K3);} @Overridepublic binarytreenode insert (int value, binarytreenode t) {if (t == null) {Return new binarytreenode (value);} The insertion value is compared to the current node, less than the insert to the left subtree, greater than the insert to right subtree if (VALUE&NBSP;<&NBSP;T.V) {T.leftchild = insert (value,t.leftchild); /Determine if the balance is broken if (height (t.leftchild) - height (t.rightchild) == 2) {if (value < T.LEFTCHILD.V) {t = rotatewithleftchild (t);} Else if (VALUE&NBSP;>&NBSP;T.LEFTCHILD.V) {t = doublewithleftchild (t);} Else{/*impossible do nothing*/}}}else if (VALUE&NBSP;>&NBSP;T.V) {t.rightChild = Insert (value,t.rightchild);//Determine if the balance is broken if (height (t.rightchild) - height (t.leftchild) == 2) { if (VALUE&NBSP;>&NBSP;T.RIGHTCHILD.V) {t = rotatewithrightchild (t);} ELSE&NBSP;IF (VALUE&NBSP;<&NBSP;T.RIGHTCHILD.V) {t = doublewithrightchild (t);} else{/*impossible do nothing*/}}}else{/*equal,do nothing*/}//Update Height T.height = math.max ( Height (t.leftchild), height (t.rightchild)) + 1;return t;}}
Using groovy for unit testing, while using the middle-order traversal output, is more intuitive:
Import static org.junit.assert.*;import org.junit.before;import org.junit.test;import binarytree.binarysorttree.binarytreenode;class testbinarytree {int[] date = [ 1,6,4,3,9,2,8,7] @Testpublic void testbinarysorttree () {binarysorttree tree = new binarysorttree ();d Ate.each{tree.insert (it);} Show (tree); Assertequals tree.getroot (). rightchild.leftchild.v,4} @Testpublic void testavltree () { Avltree tree = new avltree ();d Ate.each{tree.insert (it);} Show (tree); Assertequals tree.getroot (). Leftchild.rightchild.v,3tree.insert (5) show (tree); assertequals tree.getroot (). Rightchild.leftchild.leftchild.v,5}private static void show (BinarySortTree t) {print (T.getroot (), 0)}private static void print (binarytreenode root,int depth {if (root != null) {print (root.leftchild,depth+1);p rintprefix (depth); System.out.println (ROOT.V);p rint (root.rightchild,depth+1);}} static final string prefix = " ";p rivate static void printprefix (Int times) {while (times-->0) {if (times == 0) System.out.print ("+---"); ElseSystem.out.print (PREFIX);}}}
Resources:
"1"AVL tree and Java implementation http://www.java3z.com/cwbwebhome/article/article20/200002.html?id=4767
"2" Binary balance tree and AVL tree and Java implementation http://www.thinksaas.cn/group/topic/105579/
Java implementation of the AVL two fork sort tree