Balance a binary tree (
Balanced binary tree definition (AVL): it is either an empty tree or a binary tree of the following nature: the absolute value of the depth difference between its left subtree and the right subtree cannot exceed 1, the left and right subtree are both a balanced binary tree.
Balance factor (bf): the depth of the Left subtree of the node minus the depth of the right subtree. Obviously-1 <= bf <= 1;
Obviously, the balanced binary tree is introduced in the binary sorting tree (BST) to solve the imbalance of the binary sorting tree, resulting in a significant reduction in time complexity, so AVL will stay (BST) the best time complexity O (logn), so every insertion and deletion must ensure the balance of the binary tree, so how to maintain the balance?
I tried to look at the data structure, but only looked dizzy + _ +! I was speechless with his explanation. his so-called "rotation" operation was not clear, and it hurt me! You said that you are rotating, you have to say how it is rotating? Take that node as the center, those or those nodes are switched, and those nodes are not moving. Where do you rotate it? Who knows how you rotate it? Where do you rotate it slowly! You can't turn to me again! So I am looking for it online, just to find out how it turns out! Click the link to open it to help me understand "rotation". Thank you!
Insert:
How is it "transferred?
First, you must understand a core operation so that it cannot be called "Rotating "! --> "Transformation of two nodes"
Take the first one for example-> point 100 and 101 transformations:
Point 101 occupies 100 of the data point, and point 100 changes to the opposite position of point 101. The relative positions of other points remain unchanged.
We can intuitively understand that we can "Raise up" the 101 node!
Analysis: 101> 100, so 100 can be used as the left child of 101;
That is, in the binary sorting tree, the transformation operation of the two nodes is feasible and is in line with the nature of the binary sorting tree.
Not only can this simple graph be used for any complicated binary sorting tree, but you can try it. Maybe you will say what if there is a child on the left side of node 101? Don't worry ~, Of course there is a way!
The following describes the four imbalance conditions (during insertion) and operations of the figure:
First, you also need to understand the concept-> Minimum imbalance of the root node of the subtree: that is, when you perform the insert operation, find the location of the node to be inserted and insert it, start from this node and look up (Backtrack). The first unbalanced node is that the balance factor bf is changed to-2 or 2.
Why should we introduce this concept of least unbalanced Root Node? Because the balance factor of other nodes does not change after the sub-tree is balanced during insertion, that is, the entire tree is restored to balance. Why?
You think the bf of the non-equilibrium point must be-2 or 2. After the balancing operation, he will allocate a node of one subtree to the Child tree of the other, that is to say, the depth of one side is allocated to the other side. This balances the situation!
For example, before insertion: depth 1 on the left, depth 0 on the right, depth 2 on the left after insertion, depth 0 on the right, depth 1 on the left after equilibrium, and depth 1 on the right;
So did you say that the depth of the subtree led by the root node changes before and after insertion ?? Still 1, apparently not changed! Then the balance of the tree is maintained!
The following are the four situations: Left, right, right, left, right, left, and right. There are two more diagrams in each case: ①, ②, ① is the simplest figure in this case, ② is the general figure of the situation;
Set x to the root node of the minimum unbalanced subtree, and y to the newly inserted vertex.
Left:
That is, insert a node y (which can also be c, ①) on the left child c of x, that is, y can be c, it can also be c's left child (②) or c's right child (not drawn)
Figure ① needless to say, if the transformation between node x and node a balances the tree, then fig ② is the general situation in the tree that node a has the right child d, then we need to perform the x and a transformations. Where should the right child of a put?
Put it on the left child of x. Analysis: x> d, d> a. Therefore, d can be the left child of x and the child of. The following similar situations will not be analyzed one by one. You can analyze them yourself ~
Implementation: Find the root node x and exchange it with its left child a to rebalance the binary tree;
Right:
That is, insert a node y (which can also be c, ①) on the Right Child c of x, that is, y can be c, it can also be c's right child (②) or c's left child (not drawn)
Implementation: Find the root node x and exchange it with its right child a to rebalance the binary tree;
Left and right:
That is, insert a node y (which can also be c, ①) on the Right Child c of the left child of x, that is, y can be c, it can also be c's right child (②) or c's left child (not drawn)
This is a little complicated between the left and right sides and the right left of the bottom. Two exchanges are required to achieve the balance. Note that y is the right child of c and eventually y is the left child of x; if y is the left child of c
Right child, drawing analysis ~~ The following is similar and will not be described.
Implementation: Find the root node x, let the left child a of x exchange with the right Child c of the left child a of x, and then let x exchange with the left child c of x at this time, eventually reaching a balance;
Right left:
That is, insert a node y (which can also be c, ①) on the left child c of right child a of x, that is, y can be c, it can also be c's right child (②) or c's left child (not drawn)
Implementation: Find the root node x, let the right child a of x exchange with the left child c of the right child a of x, and then let x exchange with the right Child c of x at this time, eventually reaching a balance;
The four situations above contain all the situations that lead to imbalance during insertion. The above section only shows the minimum imbalance subtree in a big tree. Be sure to be clear!
In addition, be sure to pay attention to this switching operation. For example, if a is switched with B (a is on and B is on), B must occupy the position of! What does it mean? That is, B should be placed on the memory that stores a (overwrite,
In other words, if a is the left child of x, B is the left child of x after the exchange. This is the so-called B occupies the position of!
So how can we find the root node x of the minimal imbalance subtree and determine which situation it belongs?
When inserting a knot, we first find the location to be inserted and insert it. The data structure uses recursion. Do not say that recursion is a waste of time and space, think about the depth of a balanced binary tree with 2 ^ 31 nodes. It is more than 31 layers after recursion! Recursive code is short, lean, and rich in the beauty of art! So I think recursion is suitable for this balanced binary tree!
Obviously, after insertion, check whether there are unbalanced nodes. How can we check?
We know that when you insert data, we use recursion. A line is used to locate the position to be inserted and insert the data. Which of the following balance factors may change?
It is hard to imagine that the balance factor of the online node may change! So we can't find the first unbalanced subtree Node during backtracking ?!
But how can we determine whether the balance factor of the node should be changed depends on whether the depth of the side of the inserted node increases;
How can we see if the depth of one side of the inserted node increases?
For example, how can we see the depth increase of x's right Child a (that is, the side of the inserted node? We know that if node y is inserted to the right child of a, the bf OF a must be reduced by 1.
So the bf of the x node? You can decide whether to change according to a's bf!
If a: bf =-1 or 1, a must be 0, indicating that the depth of a is increased, then, the bf of x can be determined based on the child on which side of a is x + 1 or-1;
If a: bf = 0, a must be-1 or 1 before a, indicating that not only does the bf of x not need to be changed, the bf of all nodes on this line does not need to be changed. You can directly return the bf;
Of course, how can we determine the root node x of the minimum unbalanced subtree?
① Based on the above situations, we need to know two directions. During backtracking, we can record the direction from this node to the next node 0: Left, 1: Right is the second direction, if it is passed to the upper layer, the direction in the upper layer is one direction. With these two directions, we can determine which imbalance is involved.
Let's talk about the figure above ~ You can define a global variable secdirection (second direction) or a local variable in recursion and return it to the previous layer. When going back to a, secdirection = 1, to x
X-> the direction of a is also 1, which defines firdirection = 1; and then x: bf =-2; then the root node x of the minimum imbalance subtree is found, if you know the two directions again, you will not be able to perform the corresponding balancing operation.
② Actually, I wrote the code according to ①, but I just thought about it again. In fact, I don't need to use a variable to record the second direction. I can determine its second direction based on bf of, a: bf =-1 indicates that the depth of the right child is increased, and y indicates that the right child is added;
A: bf = 1, indicating that the depth of the left child is increased, and y is added to the left child;
Okay, I found the root node x of the minimal imbalance subtree, and I also knew the imbalance. Call keepbalance (...) the tree is balanced, but the balance factor of some nodes is changed in the transformation ~~ What should I do?
I came out in a situation where I don't know how others have changed. In each case, there are fixed points that have changed and changed to a fixed value! For more information, please advise!
The following lists the nodes and values changed by bf after transformation (in the insert operation:
Left: front a-> bf = 1 x-> bf = 0, a-> bf = 0; right: first a-> bf =-1 and then x-> bf = 0, a-> bf = 0. Obviously, the left-left and right-right x and the-transformed bf are both 0;
Bf changes at left and right center nodes depend on bf of c!
Left and right: if c-> bf = 1, x-> bf =-1, a-> bf = 0, c-> bf = 0; if c-> bf =-1, x-> bf = 0, a-> bf = 1, c-> bf = 0; if c-> bf = 0, x-> bf = 0, a-> bf = 0, c-> bf = 0;
Left right: if c-> bf = 1, x-> bf = 0, a-> bf =-1, c-> bf = 0; if c-> bf =-1, x-> bf = 1, a-> bf = 0, c-> bf = 0; if c-> bf = 0, x-> bf = 0, a-> bf = 0, c-> bf = 0;
It can be found that when both the left and right c-> bf are the same, the bf of x and a is the opposite.
Now, the binary tree inserted into a node is finally balanced, and the corresponding balance factor is also modified! Insertion is complete !!
When deleting:
The deletion operation is similar to the insert operation, and the egg operation is different. Special processing is required in some special cases. Of course, the core operation "keep balance" remains unchanged!
When a node is deleted, the depth of the subtree where the node is located may be reduced. When a node is inserted, the depth of the subtree where the node is located may increase,
Therefore, recursively delete a knot point, find the root point of the Child tree with the minimum imbalance during backtracking, and find the situation in the opposite direction;
Y is the node to be deleted;
Figure ①: After the y node is deleted, the x node x: bf =-1 is changed to x: bf =-2; then you need to check the situation from the opposite direction, that is, from the direction of the right child of x. Obviously, the first direction is 1: Right;
In the second direction, a: bf value -- if it is 1, it is equivalent to 'rightleft' when inserting; if it is-1, that is equivalent to the 'left left' case when inserting; but now a: bf neither 1 nor-1
It is 0, which is the special case of deletion! Let's try to operate on him like the 'right right' operation during insertion ~ For example, after the transformation, the subtree is balanced! But factor
The modification is different from the 'right' at the time of insertion! This changes to: x: bf =-1, a: bf = 1; so we may consider: bf = 0 is also classified as the 'right right' or 'left left' operation to be deleted (②, not described again;
When deleting a factor, you must add the following to the change of the factor during insertion:
Left: Front a: bf = 0 x: bf = 1, a: bf =-1; Right: Front a: bf = 0 x: bf =-1,: bf = 1; others remain unchanged!
End the modification of the node balancing factor at the time of insertion and return directly (that is, the tree has been balanced ):
When backtracking, the balance factor of the son node is found to be 0 (when an unbalanced node is found and the balance operation is performed, the bf of the root node after the balance must be 0, and it is also over)
However, if you modify the End Node balance factor when deleting the node, the result is returned directly, which is different from that when you insert the node. During backtracking, you can find that the balance factor of the son node is-1 or 1!
In the delete operation, after balancing a subtree, the depth of the subtree is not necessarily the same, and the depth of the subtree remains the same only in the special circumstances above, and others will change!
As you can imagine, it is actually quite simple: except in special cases, everything is exactly the same as the insert situation. To put it bluntly, it is to put the child tree with a large depth (one of the root nodes) contribute depth to the deep kidtree,
In this way, the depth of the subtree (for the tree headed by the root node) is 1 lower than that of the original one ?! So we need to continue to search one by one until the root node!
How does one understand a balanced binary tree?
This involves the problem of full Binary Trees and full Binary Trees.
A full Binary Tree is a binary tree that fully occupies n layers. layer n has 2 ^ n elements;
The n-layer full Binary Tree removes less than 2 ^ n elements from the back and forward of the n-layer full binary tree;
A full Binary Tree is a special case of a balanced binary tree. A balanced binary tree is a binary tree that distributes the last element of a Complete Binary Tree to any space.
As shown in, the left is a full binary tree, and the right is a full Binary Tree:
Balanced binary tree Definition
The so-called balanced binary tree means that the left and right subtree heights of any node in the tree are roughly the same. The balanced binary tree was proposed by the former Soviet mathematician Adelse-Velskil and Landis in 1962, called the AVL Tree. A balanced binary tree (AVL Tree) is defined as follows: a balanced binary tree, an empty tree, or a binary sorting tree of the following properties: (1) the absolute value of the height difference between the left subtree and the right subtree cannot exceed 1; (2) the left subtree and the right subtree are both balanced binary trees.