Java implementation of Balanced binary tree (avltree) construction

Source: Internet
Author: User
Tags comparable

Recently in the study of data structure on the balance of binary tree knowledge, look at strict teacher's thinking, feel a bit difficult to write a recursive construction method in Java, because the recursion needs to pass in the reference, so the feeling is to achieve a more troublesome, so the first thought of using a non-recursive way to achieve the construction of balanced binary tree.

Using a non-recursive approach, the idea is simple, is to define a balance factor for each node of the attribute, when the success of inserting a data into the tree, I will go back to see if there is no balance factor of the absolute value equals 2 of the node, if there is, it needs to be rotated. At that time, the idea was limited to these, the contact with Java not long, visual inspection if implemented, a bit difficult.

Therefore, the Internet query a blog to write code, although do not know who the original author, but still affixed to my reference blog address: http://blog.csdn.net/zxman660/article/details/7940190

Among them, I think there is a problem is that I define the node using generics, that is, the node value is also used in the generic <e>, so in comparison size, I do not know, may be I contact Java for not too long reason, when I refer to the above blog's ideas, incredibly this realization.

void Compare (e element, node node) {comparable<? super e> E = (comparable<? super e>) element; int cmp = E.comp Areto (node.element); if (CMP > 0)//greater than else if (CMP = = 0)//equals else//less}

Through this study, although contact with the balance of binary tree construction, but still feel learned a lot of knowledge, and the use of Java has more understanding.

With the above sentiment, feel or write a blog to collect, and so you have time, and then add the node deletion code.

Perhaps I code in the comments on the idea of a limited, if there is not understand the place, you can refer to the above blog address content.

Package util;/** * Balanced binary tree * Definition: First it is a special two-fork sorting tree, followed by its Saozi right subtree is balanced binary tree, * and Saozi right subtree depth difference not more than 1 * balance factor: can be defined as the depth of the Zuozi minus the depth of the right subtree * * The Balanced binary tree is the optimization of the two-fork sorting tree, which prevents the binary sort tree from finding the average time in the worst case of N, * binary sort tree in this time shape as a single linked list * Balanced binary tree The number of times to find elements does not exceed the depth of the tree, the time complexity is LOGN */public class Avltree<e > {/** root node */private node<e> root = number of elements in null;/** tree */private int size = 0;private static final int left_high = 1;PR ivate static final int right_high = -1;private static final int equal_high = 0;public Avltree () {}public Boolean Insertelem ENT (E element) {node<e> t = root;if (t = = null) {/** Copies the value to the root node whose parent is empty */root = new node (element, null); size = 1;return Tru e;} int cmp = 0; Node<e> parent; /** is used to save the parent node of the T *//** find the location */comparable&lt the node should be stored; Super e> E = (comparable<? super e>) Element;do{parent = t;cmp = E.compareto (t.element); if (CMP < 0) {t = T.left; }else if (cmp > 0) {t = t.right;} Else{return false;}} while (t! = null),/** stores the node in the appropriate location */node<e> child = new Node (element, parent), if (CMP < 0) {parent.left = child;} Else{parent.rigHT = child;} /** begins backtracking, modifying the BALABCE for the root node so that the corresponding adjustment */while (parent! = NULL) {CMP = E.compareto (parent.element); if (CMP < 0) { Parent.balance + +;} Else{parent.balance--;} if (parent.balance = = 0) {/** from the above nodes need not be modified, do not need to rotate the */break;} if (Math.Abs (parent.balance) = = 2) {fixafterinsertion (parent); break;} parent = parent.parent;} Size ++;return true;} private void Fixafterinsertion (Node<e> p) {if (p.balance = = 2) {leftbanance (P);} if (p.balance = =-2) {rightbalance (P);}}  /** * Left balance operation, that is, the imbalance of the node T is because the left dial hand tree is too deep * * 1, if the new node is inserted into the left child of P-left subtree, then the right-hand operation can be directly * TLC */\ Right-spin/* LC RC-------------> LCL T */\//* LCL LCR LCLL LCR RC */* LCLL * 2, if a new node is inserted into the right subtree of P's left child, a sub-case discussion is required *                 Condition A: When P's left child's right child tree root node balance = Right_high * 11 4 */\/\/* 2 6 L 4 6                      Right-handed 2 1 */\------->/\-------->//* 3 4 2 5 3 5 6 * \/*             5 3 * * * case B: When P's left child's right child tree root node balance = Left_high * 11 4 */\/\/* 2 6 left-handed                  4 6 Right-handed 2 1 */\------->/-------->/\ * 3 4 2 3 5 6 *//* 5 3 5 * * Case C: When P's left child's right child root  Balance of the node = equal_high * * 11 4 */\/\/* 2 7 L 4 7 right-hand 2 1 */   \------->/\-------->/\/* 3 4 2 6 3 5 6 7 */\/* 5 6 3 5 * */private void leftbanance (Node<e> t) {NODE&LT;E&G T LC = T.left;switch (lc.balance) {Case left_high:/** new node inserted into T left child's left subtree, requires single right-hand processing */lc.balance = Equal_high;t.balance = Equal_ High;break;case right_high:/** new node is inserted into the left child's right subtree of T, requires a double spin process */node<e> rd = Lc.right;switch (rd.balance) {case Left_ HIGH:lc.balance = Equal_high;t.balanCe = right_high;break;case RIGHT_HIGH:lc.balance = left_high;t.balance = Equal_high;break;case Equal_high:t.balance = Equal_high;lc.balance = Equal_high;break;} Rd.balance = equal_high;/** Left-handed */left_rotate (T.left) to the left subtree of T,/** right-handed to T */right_rotate (t); break;}}   /** * Right balance operation, that is, the imbalance of the node T is because the right subtree is too deep * * 1, if the new node is inserted into the right child right subtree of p, then the direct left-hand operation can be * * PR */\/* L R Left-hand operation P RR */ \----------->/\ * RL RRL RL RRR * * RRR * * * 2, if a new node is inserted into the left subtree of the right child of P, a sub-case discussion is required * case  A: When P's right child's Zogen node balance = Left_high * *114 */\/\/* 2 3 right-hand 2 4 left-handed 1 3 */\------->  /\------->/\ * 4 5 6 326 5 */* 65 * * case B: When P's right child's Zogen node balance = Right_high * *114 */    \/\/* 2 3 right-handed 2 4 left-handed 1 3 */\-------> \------->//* 4 5 32 6 5 * \/* 66 5 * * * Case c: When P's right child's Zogen node balance = equal_high *114 */\/\/* 2 3 Right spin 2 4 left Spin 1 3 */\------->/\------->/\/* 4 5 6 326 7 5 */\/* 6 + 5 * */private void righ Tbalance (node<e> p) {node<e> rc = P.right;switch (rc.balance) {Case right_high:/** new node inserted into T right child's right subtree, requires single left-handed processing */rc.balance = Equal_high;p.balance = equal_high;break;case left_high:/** The new node is inserted into the left subtree of the right child of T, the double-spin processing is required for the */node<e> ld = Rc.left;switch (ld.balance) {case left_high:p.balance = Equal_high;rc.balance = Right_high;break;case RIGHT_HIGH: P.balance = Left_high;rc.balance = Equal_high;break;case equal_high:p.balance = equal_high;rc.balance = EQUAL_HIGH; break;} Ld.balance = equal_high;/** Right-handed */right_rotate (p.right) to the right subtree of P,/** to p for left-hand processing */left_rotate (p); break;}} /** * Left-handed operation * PR */\/* L R Left-hand operation P RR */\----------->/\ * RL RRL RL RR R * * RRR * */private void Left_rotate (node<e> p) {if (P! = null) {node<e> r = p.right;/** Get P's right subtree root node R*/p.ri Ght = r.left;/** The left subtree of R is transferred to the right subtree of P */if (r.left! = null) {/** If R's left subtree is not empty, the left sub-treeThe parent node of the tree is set to P*/r.left.parent = p;} R.parent = p.parent;/** modifies the parent node of R, modifies the parent node of P */if (p.parent = = null) {/** If the parent node of P is null, then r is the root node */root = r;} else if (p = = p.parent.left) {/** If P is the left child of its parent node, the left child of its parent node points to R*/p.parent.left = R;} else if (p = = p.parent.right) {/** If P is the right child of its parent node, point the right child of its parent node to R*/p.parent.right = R;}   R.left = p;/** Set R's left child to P*/p.parent = r;/** the parent node of P is set to r*/}}/** * right-hand operation * PL */\ Right-hand operation/* L R-------------> ll p */\//* LL lrlll LR R */* LLL * */private void Right_rotate (node<e> p) {if (P! = NULL {node<e> L = p.left;/** gets P's Left child l*/p.left = l.right;/** turns the right subtree of L to the left subtree of P */if (l.right! = null) {/** If the right subtree of L is not empty, Set its parent node to p*/l.right.parent = p;} L.parent = p.parent;/** modifies the parent node of R to the parent of P */if (p.parent = = null) {/** If the parent node of P is null, that is, l is Root*/root = l;} else if (p = = p.parent.left) {/** If P is the left child of its parent node, the left child of P's parent node points to L*/p.parent.left = l;} else if (p = = p.parent.right) {/** If P is the right child of its parent node, the right child of P's parent node points to L*/p.parent.right = l;} L.right = p;/** Changes the right subtree of l to P*/p.parent = l;/** modifies the parent node of P to l*/}}/** the non-recursive way to traverse the balanced binary tree */public void Nrinordertraverse () {stack<node<e>> Stack = new stack<node<e>> (); Node<e> p = root;while (P! = NULL | |!stack.isempty ()) {while (P! = null) {Stack.push (p);p = P.left;} p = Stack.pop (); System.out.println (p.element);p = P.right;}} The node definition of/** balanced binary tree */class node<e>{e element;/** node balance factor */int balance = 0;/** left child node, right child node, parent */node<e> Ieft; Node<e> right; Node<e> parent;public node () {}public node (E element, node<e> parent) {this.element = Element;this.parent = Parent;} Public String toString () {return element + "bf=" + Balance;}} public static void Main (string[] args) {integer[] num = {5,8,2,0,1,-2,-9, 100}; avltree<integer> AVL = new avltree<integer> (); for (int i = 0; i < num.length; i++) {avl.insertelement (Num[i] );} Avl.nrinordertraverse ();}}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.