"Data structure" balance binary sort tree Bbst of AVL tree

Source: Internet
Author: User

Balanced binary sorting tree

Balanced binary sorting tree (Balanced binary sort trees), previous blog "Data structure" binary sort tree BST spoke BST, and at the end we said that the operation on BST would not exceed O (h), since tree height is so important, So Bbst's study is to make the depth of the tree reach O (LGN) within an acceptable range.

n nodes of the two-tree, the height of the LGN to remove the time limit, the tree is ideal balance, meet such conditions of the tree only a complete binary tree and full of two fork tree, such requirements are too harsh, and in practice there is no meaning.

Moderate balance: A tree that ensures that the tree height is not more than O (LGN) moderately balanced in the asymptotic sense is also called a balanced binary tree.

And we know that any balanced two-fork tree may be unbalanced after a series of insertions and deletions, so any bbst contains a way to define the standard of balance and a series of heavy balances (rebalance).

Balanced binary sorting tree includes: AVL tree, red black tree, stretching tree, etc.


AVL TreeAVL tree is only a balanced binary tree, it is the most classic of the earliest invention of a bbst (seemingly Min teacher's book that balanced binary tree also known as AVL tree), AVL tree by G.M. Adelson-velsky and E.M. Landis invented.
AVL defines the standard of moderate balance:
Define balance Factor (Balancefactor): BF (node) = height (lchild (node))-Height (rchild (node))
node for all nodes, there | BF (node) | <= 1

A series of re-balancing methods: rotation operation

The basic rotation operation is as shown


It is divided into four situations according to different situations.


Correlation Algorithm1. Return height of a node
We set the height of 1 when the node is null, and the height of the remaining cases is maintained by each node itself.
private int height (binarytreenode node) {if (node = = null) {return-1;} else {return node.height;}}

2. Return the balance factor of a node
Balance factor equals Zuozi height minus right sub-tree height
private int balance (Binarytreenode node) {if (node = = null) return 0;return height (node.lchild)-height (node.rchild);}

3. Left-handed LL

The TMP is returned as the final root node in three steps in the order of the diagram.

additional work is required to assign a new parent to a node that has been changed by the parents, update the height, and eventually return the node to the father nodes must be set at the call !!
LL   will node node to the left, node is the root of the smallest unbalanced subtree public binarytreenode leftrotate (Binarytreenode node) {Binarytreenode TMP = Node.lchild;tmp.parent = Null;node.lchild = Tmp.rchild;if (tmp.rchild! = null) tmp.rchild.parent = node;tmp.rchild = node; node.parent = tmp;//update height, including node and node.rchildnode.height = Math.max (height (node.lchild), height (node.rchild)) + 1; Tmp.height = Math.max (height (tmp.lchild), node.height) + 1;return tmp;}

4. Double-spin LR
In two steps, the left sub-tree of the node is left-handed operation, and then the node to the right-hand operation, to be careful to save the first return of the node of the Father node!!
Public Binarytreenode Leftrightrotate (Binarytreenode node) {node.lchild = Rightrotate (node.lchild); node.lchild.parent = node; Parent node Assignment!! return leftrotate (node);}

5. Return the rotation type of the node to be rotated
Private Rotatetype Rotatetype (Binarytreenode node) {if (Balance (node) <-1) {if (balance (Node.rchild) > 0) {return R OTATETYPE.RL;} else {return ROTATETYPE.RR;}} else {//>1if (Balance (Node.lchild) < 0) {return ROTATETYPE.LR;} else {return rotatetype.ll;}}}

6. Instead of node, the subtrees tree is used for node to rotate the vertex.

Replace function void Replace with before difference (Binarytreenode Node1, Binarytreenode node2)

after the node A is rotated, theparent node of A is changed, so the parent node is saved so that the rotated subtree is hung behind it. , so the call to the function does not equal the call to replace (node,leftrotate (node), type);

Mosaic rotated subtree: Use node as a fixed point to rotate the tree instead of node this subtrees tree private void ReplaceNode (Binarytreenode node, Rotatetype type) {Binarytreenode Tmpparent = node.parent; Binarytreenode Rotatenode = Null;switch (type) {Case ll:rotatenode = leftrotate (node); Break;case Rr:rotatenode = RightRot Ate (node), break;case Lr:rotatenode = leftrightrotate (node), break;case Rl:rotatenode = rightleftrotate (node); if (tmpparent = = null) {root = Rotatenode;rotatenode.parent = null;//parent node assignment is critical!! } else if (Tmpparent.rchild = = node) {Tmpparent.rchild = Rotatenode;rotatenode.parent = root;//parent node assignment is critical!! } else {tmpparent.lchild = Rotatenode;rotatenode.parent = root;//parent node assignment is critical!! }}


inserting and deleting

With some of the basic functions above, you can do two important things: insert/delete nodes

inserting Nodes when inserting a node may cause his grandfather's knot imbalance, and the great-grandfather's knot will be unbalanced and so on. So it seems that the insert operation is complicated? This is not the case, however, we do not need to adjust the nodes from the bottom to the balance. Because the good news is that the sub-tree balancing of the first unbalanced node from bottom to top can guarantee all the nodal balances on top of it. the sub-tree of the first unbalanced node here is called the smallest unbalanced subtree. Adjusts the minimum unbalance subtree to the heavy balance, its height is unchanged from the insertion node, and therefore does not affect the upper node. This requires only a limited number of steps to re-balance the complexity of O (1).

Each node inserted here will update the height of the existing nodes! The implementation of the insertion is the same as in BST, just to update the node height.

Private Binarytreenode Insertrecuravl (Binarytreenode root,binarytreenode insertnode) {if (this.root = = null) {This.root = root = Insertnode;} else if (Insertnode.data < root.data && Root.lchild = = null) {Root.lchild = Insertnode;insertnode.parent = root ;} else if (insertnode.data >= root.data && root.rchild = = null) {Root.rchild = Insertnode;insertnode.parent = Roo t;} else {if (Insertnode.data < Root.data && Root.lchild! = null) Insertrecuravl (Root.lchild, Insertnode); Insertnode.data >= root.data && root.rchild! = null) Insertrecuravl (Root.rchild, Insertnode);} Update Height! Root.height = Math.max (height (root.lchild), height (root.rchild)) + 1;//Place here is important return insertnode;}
so the code to check the balance after inserting the node is the following, the basic idea is to insert the new node in the corresponding position, and then from the beginning he went up, until he encountered the first unbalanced node, that is, the smallest unbalanced subtree,
Then rotate the node to restore the balance and replace the node later.
public void Insertavl (Binarytreenode insertnode) {binarytreenode node = Insertrecuravl (root, Insertnode);// Adjust the minimum unbalance subtree while (node! = null && balance (node) >-2 && Balance (node) < 2) {node = node.parent;}//Jump out Loop, node is null or node unbalanced if (node! = NULL) {//determines what kind of rotation rotatetype type = rotatetype (node); ReplaceNode (node, type);}}
The process of creating a bbst from an array can also be inserted through an insert operation.

Delete a node.

Deleting a node can only cause his father's node to be unbalanced, because, If we delete the deepest of the tree, then it will not be unbalanced, so the imbalance can only be caused by the deletion of the nodes on the short subtree, so that the outside world, the father of the node is the height of the subtree is unchanged, so the balance of the above node will not change. So the delete operation only needs to rebalance its parent node? In fact, deleting a node his father if there is an imbalance, then when the Father node is rebalanced, the height of the local subtree is reduced, so the imbalance may continue to pass up, the worst case has been passed to the root, so the complexity of the deletion is O (LGN). in fact, for this reason, the AVL tree is not used much, SGI STL is not real AVL tree, only implemented the red black tree

//delete nodes in the AVL tree public void Deleteavl (Binarytreenode node) {System.out.println ( Node.tostring ());        Binarytreenode predecessorofnode = null;          if (Node.lchild = = null) {///left dial hand tree is empty, only need to transplant right subtree replace (node, node.rchild);          } else if (Node.rchild = = null) {Replace (node, node.lchild);              } else {Predecessorofnode = predecessor (node);              Replace (node, node.lchild);              Predecessorofnode.rchild = Node.rchild;            Node.rchild.parent = Predecessorofnode;        Predecessorofnode.height = Math.max (height (predecessorofnode.lchild), height (node.rchild)) + 1; }//Adjust balance//Only need to start from the precursor of the deleted node to judge Binarytreenode nodetmp = Predecessorofnode;while (nodetmp! = null) {Binarytreenode TMP = no Detmp.parent; The following rotation action will change the parent node of nodetmp, so save it in advance!!  if (balance (NODETMP) <-1 | | balance (NODETMP) > 1) {//unbalanced Rotatetype type = Rotatetype (nodetmp); ReplaceNode (Nodetmp, type);} NODETMP = tmp;}} 


implementation of AVL tree

The Binarytreenode used has a height field that is used to hold the height of each node, which is 1 when the junction is null.

public class Avltree extends Binarysearchtree {public enum Rotatetype {LL, RR, LR, RL}; @Overridepublic void Createtree (int [] array) {//Create two forks from an array search tree for (int i:array) {Insertavl (new Binarytreenode (i));}}  Delete node public void Deleteavl (Binarytreenode node) {Binarytreenode Predecessorofnode = null;if (Node.lchild = = null) in the AVL tree {//Left dial hand tree is empty, only need to transplant right subtree replace (node, node.rchild);} else if (Node.rchild = = null) {Replace (node, node.lchild);} else {predecessorofnode = predecessor (node); Replace (node, nod E.lchild);p redecessorofnode.rchild = Node.rchild;node.rchild.parent = Predecessorofnode;predecessorofnode.height = Math.max (height (predecessorofnode.lchild), height (node.rchild)) + 1;} Adjust balance//Only need to start from the precursor of the deleted node to judge Binarytreenode nodetmp = Predecessorofnode;while (nodetmp! = null) {Binarytreenode TMP = nod Etmp.parent; The following rotation action will change the parent node of nodetmp, so save it in advance!!  if (balance (NODETMP) <-1 | | balance (NODETMP) > 1) {//unbalanced Rotatetype type = Rotatetype (nodetmp); ReplaceNode (Nodetmp, type);} NODETMP = tmp;}} Insertnode and handle possible unbalanced nodes public void Insertavl (Binarytreenode insertnode) {binarytreenode node = Insertrecuravl (root, Insertnode); while (node = null && balance (node) >-2 && Balance (node) < 2) {node = node.parent;}//Jump out of the loop, node is Null or node unbalanced if (node! = NULL) {//determines what kind of rotation rotatetype type = rotatetype (node); ReplaceNode (node, type);}} Recursively inserts the node, updating the height of each node at the same time private Binarytreenode Insertrecuravl (Binarytreenode root,binarytreenode insertnode) {if ( This.root = = null) {This.root = root = Insertnode;} else if (Insertnode.data < root.data && Root.lchild = = NULL {Root.lchild = Insertnode;insertnode.parent = root;} else if (insertnode.data >= root.data && root.rchild = = null) {Root.rchild = Insertnode;insertnode.parent = Roo t;} else {if (Insertnode.data < Root.data && Root.lchild! = null) Insertrecuravl (Root.lchild, Insertnode); Insertnode.data >= root.data && root.rchild! = null) Insertrecuravl (Root.rchild, Insertnode);} Root.height = Math. Max (height (root.lchild), height (root.rchild)) + 1;//Place here is important return insertnode;} Mosaic rotated subtree: Use node as a fixed point to rotate the tree instead of node this subtrees tree private void ReplaceNode (Binarytreenode node, Rotatetype type) {Binarytreenode Tmpparent = node.parent; Binarytreenode Rotatenode = Null;switch (type) {Case ll:rotatenode = leftrotate (node); Break;case Rr:rotatenode = RightRot Ate (node), break;case Lr:rotatenode = leftrightrotate (node), break;case Rl:rotatenode = rightleftrotate (node); if (tmpparent = = null) {root = Rotatenode;rotatenode.parent = null;//parent node assignment is critical!! } else if (Tmpparent.rchild = = node) {Tmpparent.rchild = Rotatenode;rotatenode.parent = root;//parent node assignment is critical!! } else {tmpparent.lchild = Rotatenode;rotatenode.parent = root;//parent node assignment is critical!! }}//gets the rotation type of the node to be rotated private rotatetype Rotatetype (Binarytreenode node) {if (Balance (node) <-1) {if (Balance (node.rchild ) > 0) {return rotatetype.rl;} else {return ROTATETYPE.RR;}} else {//>1if (Balance (Node.lchild) < 0) {return ROTATETYPE.LR;} else {return RotAtetype.ll;}}}  Return node balance factor return value is -2-1 0 1 2private int balance (Binarytreenode node) {if (node = = null) return 0;return height (node.lchild) -Height (node.rchild);} The height of the rebate for a node private int height (binarytreenode node) {if (node = = null) {return-1;} else {return node.height;}} The node node is left-handed, and node is the root of the smallest unbalanced subtree//rrpublic binarytreenode Rightrotate (Binarytreenode node) {Binarytreenode TMP = Node.rchild;tmp.parent = Null;node.rchild = Tmp.lchild;if (tmp.lchild! = null) tmp.lchild.parent = node;tmp.lchild = node; node.parent = tmp;//update height, including node and node.rchildnode.height = Math.max (height (node.lchild), height (node.rchild)) + 1; Tmp.height = Math.max (height (tmp.rchild), node.height) + 1;return tmp;} The node node is left-handed, and node is the root of the smallest unbalanced subtree//llpublic binarytreenode Leftrotate (Binarytreenode node) {Binarytreenode TMP = Node.lchild  ; tmp.parent = Null;node.lchild = Tmp.rchild;if (tmp.rchild! = null) Tmp.rchild.parent = Node;tmp.rchild = Node;node.parent = tmp;//update height, including node and node.rchildnode.height = Math.max (Height (node.lchild), height (node.rchild)) + 1;tmp.height = Math.max (height (tmp.lchild), node.height) + 1;return tmp;} Lrpublic binarytreenode Leftrightrotate (Binarytreenode node) {node.lchild = Rightrotate (node.lchild); Node.lchild.parent = Node;return leftrotate (node);} Rlpublic binarytreenode Rightleftrotate (Binarytreenode node) {node.rchild = Leftrotate (node.rchild); Node.rchild.parent = Node;return rightrotate (node);}}
Test

Still use the array of the previous blog to create BST int[] array = {1, 9, 2, 7, 4, 5, 3, 6, 8};

public static void Main (string[] args) {Avltree AVL = new Avltree (); int[] array = {1, 9, 2, 7, 4, 5, 3, 6, 8};avl.create Tree (array); SYSTEM.OUT.PRINTLN ("Sequence print node and its height"); Avl.levelorderh (); System.out.println ("Remove the sequence traversal from Node 7"); Avl.deleteavl (Avl.search (Avl.root, 7)); Avl.levelorderh ();}

Output

Sequence print node and its height 4  2  7  1  3 5 9  6  8  Delete node 7 get the sequence traversal 4  2 8  1  3  5  9  
It can be found that the array was built into BST, the tree height is very high, now it is built into the AVL tree, found a very balanced, tree height is much lower than before. And the balance of the tree can always be maintained during dynamic insertion and deletion.

Analysis

The process of parsing the creation and deletion nodes of the array

The above code creates the AVL tree through the array the process is as follows


The process of deleting a node 7



PostScript

Maybe the last code is about 200 lines, but it is difficult to make a few, compared to writing an application minutes thousands of lines of code more difficult, changed the bug changed a night. Since I am here to save the parent node, I forgot to assign the parent node several times, when rotating, because the pointer changes will also cause a lot of problems, writing code in the process of encountering errors caused by the code in the place.

"Data structure" balance binary sort tree Bbst of AVL tree

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.