The previous blog mainly describes the basic concept of two-fork sorting tree and insert delete operation, it must be explained again: In a height of two-fork sorting tree, the implementation of dynamic collection operation query, insert and delete run time is O (h).
The basic operational efficiency of the binary tree is determined by the shape of the tree, of course, the lower the height of the tree is better, obviously, the more evenly distributed tree, the lower the height. So, what's the problem? For a given keyword sequence, how to construct a two-fork sort tree with a symmetrical shape. This symmetrical two-fork sort tree is called a balanced binary tree.
Balanced binary tree definition: Balance a binary tree or an empty tree, or any node on it, the left and right sub-tree height difference of the node does not exceed 1. The difference between the height of the left and right subtrees of all nodes on a two-fork tree is usually called the equilibrium factor .
The commonly used algorithms for constructing balanced binary trees are AVL trees and red-black trees. Among them, the AVL tree to maintain the balance of the mechanism of balance factor and rotation, and the red and black tree to maintain the balance of the mechanism is the node color constraints and rotation, in fact, the red and black trees do not pursue a complete balance, only partial balance: No path can be redundant other paths twice times longer, but red black trees can be O (log2 The time complexity of the query delete insert operation. This blog first introduced AVL, the next blog to explain the red and black trees.
The basic idea of constructing an AVL tree : Whenever a new node is inserted, first check whether the tree balance is broken by insertion, while preserving the character of the binary sort tree (that is, the balanced binary tree must first ensure it is a two-fork sort tree) to adjust the point between the nodes of the least-balanced subtree, To achieve a new balance. < The so-called minimum unbalance subtree refers to a node that is closest to the insertion point and has a balance factor greater than 1 as the root subtree, in short: It is the beginning of the new insertion node position to the root node, the first one from the balance into an unbalanced node >
Compared with the two-fork sort tree, the balanced binary tree is inserted into the node to ensure that both order and balance are ensured. So the way to ensure that is: rotate
Inserting a new node n causes the balance of the binary tree to no longer be balanced, the root of the smallest unbalanced subtree is a, the insertion position is different, and the adjustment node balance factor and point are also different after inserting. Can be summarized in the following 4 cases ():
Note: The node in the graph is represented by a circle, and the subtree is represented by a rectangle, representing more than one node, possibly one, possibly multiple nodes, and a rectangular length representing the subtree height. The red flag is the pointer to the change signal.
1> LL, the new insertion node is on the left child of a left subtree : right-handed , when the new node n is added, the balance factor of Node A BF (Blancefactor) is changed from 1 to 2, in order to write a clear visual description: A.bs = 1-->2 (The following format is the same) and B.bs = 0--->1. To maintain the balance, you need node A to rotate right around B.
Image point, that is, Node A is already about to be unbalanced (Bs=1, Supi right sub-tree high), this time its left subtree added a node, this is not the last straw to crush the camel ... At this point, you need to rotate the tree to the right to reduce the height of node A. and Node B before adding n bs=0, indicating that there is the ability to withstand, this time to give it a burden, let him from the small mutiny general, ascend to the root node, so that the tree into a balance. There's a lot of crap, but good understanding. See the code for the specific adjustment process.
Right rotation processing function void R_rotate (Bstree &p) {Bstree lc;lc=p->lchild;p->lchild=lc->rchild;lc->rchild=p;p=lc;}
2>RR, the new insertion node in a right child's right sub-tree: L ; And the right-hand principle is similar, the right sub-tree is high, then a node, have to left-handed.
Left rotation processing function void L_rotate (Bstree &p) {Bstree rc;rc=p->rchild;p->rchild=rc->lchild;rc->lchild=p;p=rc;}
3>LR, the new insertion node on the right subtree of the A left subtree, first left and then right, the exact point is in a left subtree of the right sub-tree (left subtree or right child)
Operation 3> is relatively complex compared to Operation 1> and Operation 2>. The reason for this is that: before inserting a new node n, both root node A and its left subtree node B are nodes with a balance factor of not 0: that is to say a.bf=1 b.bf=-1;
That is, they are only a step away from the imbalance, and then add a node, and are added to their A's left subtree, B's right subtree under the left sub-tree, they will be crushed to death, this time, root node A child node B said, you come as the root node. b A look, my imbalance factor is not 0, can not be ah; So, b left, put C top up. To a, I can't be the root node, but C can, so, once again around C right rotation, a down, c when the root node.
, why does C work as a root node? Because the balance factor of the pre-C is 0, even if a node is added, it is still a step away from the imbalance.
See Code for specific procedures
The left balance rotation processing function---the insert operation contains a balance factor modification void leftbalance (Bstree &t) {bstree lc,rd;lc=t->lchild; Switch (LC->BF) //Check the balance of the left subtree of T, judge whether the operation 1> or Operation 3>, and make the corresponding balance processing {case LH: //Operation 1>: Do single right-hand processing t->bf=lc-> BF=EH;//1 The new node is inserted in the left subtree of T, first modify the balance factor and then right -r_rotate (T); Break;case RH: //Operation 3>rd=lc->rchild;//-1 New node inserted on the left child's right subtree of T, switch (RD->BF) {//modify T and left child's balance factor case lh:t->bf=rh;//new nodes are inserted under Rd as left subtree Lc->bf=eh;//break;case EH : T->bf=lc->bf=eh;//break;case rh:t->bf=eh;//new node is inserted under Rd as right subtree Lc->bf=lh;break;} rd->bf=eh; L_rotate (t->lchild);//Zuozi left-hand processing of T r_rotate (t);//right-handed processing of T}}
4>RL, the new insertion node is on the left sub-tree of a right subtree, first right -handed and then left-handed. The process and LR are similar and do not dwell on it.
Direct Sticker Code
Right balance rotation processing function void Rightbalance (Bstree &t) {bstree rc,ld;rc=t->rchild;switch (RC->BF) //Check the balance of right subtree of T in insert operation , and make the appropriate balance processing {case rh:t->bf=rc->bf=eh; L_rotate (T); Break;case Lh:ld=rc->lchild;switch (LD->BF) {case Lh:t->bf=eh;rc->bf=rh;break;case EH:T- >bf=rc->bf=eh;break;case Rh:t->bf=lh;rc->bf=eh;break;} ld->bf=eh; R_rotate (T->rchild); L_rotate (T);}}
From two fork sorting tree to balanced binary tree to red black Tree series 2