Data structure (XV) binary - balanced binary tree

In the previous section has outlined earlier, in certain circumstances, binary sort tree is likely to degenerate into a single list. That is, if a binary sort tree already ordered sequence of sorts, then one of the structures will degenerate into a single list, and search efficiency elements also decreased significantly, so this time we need some special tools to ensure that this binary tree sort of "balance", thus ensuring the efficiency of query elements.

First, the definition of a balanced binary tree is absolutely

   Balanced binary tree (AVL tree) is itself a binary sort tree, to comply with the same left child <root <left child or right child> root> right child characteristics between elements within. However, in the creation of a balanced binary tree, we ask any node in the tree structure, the difference between the depth of the sub-layers of depth around the tree, the absolute value does not exceed 1. For example: if one of the binary tree structure, the depth of a left subtree of a node having a depth in the range 5, its right subtree between 4-6, if less than or exceeds this range, not It is regarded as a balanced binary tree. Then insert a new node to the binary tree structure, or delete the original node, it is very likely lead to about a sub-tree node imbalance occurred, then you need to specify the nodes in the rotation, so that ultimately this the destination node, and the whole structure of a balanced binary tree.

Second, rotating node

   When we add a node to the AVL tree, or delete nodes in the tree AVL, AVL will inevitably result in the overall balance of the original tree structure becomes unbalanced on some nodes. So this time, we need to rotate AVL nodes in the tree, AVL tree node structure readjustment, and ultimately makes the AVL tree again return to equilibrium.
Fortunately, after adding a node or delete a node, we can cause an imbalance in the relationship between nodes within a maximum of four generations. So, we can be a state of imbalance in accordance with the depth of the relationship between the imbalance node and its leaf nodes are divided into three generations and four generations imbalance Imbalance. Where: three generations unbalanced situation by adding and removing nodes leads are relatively easy to understand and deal with, but when it comes to a node between 4 generations, because adding or removing elements of the imbalance caused, we need to analyze some more complex situation, but no matter how complicated the situation, we are ultimately by rotating nodes to complete the rotation of the adjustment of the balance of the AVL tree structure of nodes, according to the rotation direction and frequency can be divided into: L right-handed spin around, left and right four. Here, we come to the light of these above mentioned one by one to discuss how to adjust the balance of the AVL tree structure

1, balanced binary tree of related concepts

  • Insert node: refers to the operation by adding, adding new AVL tree structure of nodes, in addition phase of the AVL tree will not necessarily lead to an imbalance when structural changes, but we are still in discussions to add a node, use this concept.
  • Minimum unbalanced node: When adding nodes to the AVL tree, or delete nodes operation may cause imbalance in the overall structure of the AVL tree, but the overall imbalance in the AVL tree, again which is closest to the number of layers an unbalanced leaf node is more important, we call unbalanced point closest to the leaf nodes of the lowest point of imbalance

2.1, adding nodes within three generations

Case within three generations, in general, all refer to the grandparent because the insertion elements lead to an imbalance within, we are divided into three generations in the case of 4:

(1) a right-handed or so down

If you insert a node in time to join the binary tree, is mounted in the lower left child node of his grandfather, and is the left child of its parent node, and cause the entire binary tree balanced, so at this time we use the right-handed way, of binary sort tree adjustment, namely: the right-handed down Zuozuo

Dextrorotatory steps:
Step 1: the position of the parent node substituted grandparent, i.e. lifted up one
Step 2: grandparent node becomes the right child of the parent node, a parent node can not exist at this time right child node, because if present, in the last round should have been balanced by turning the adjustment
step 3: the relationship between the remaining nodes remains unchanged

(2) Right Right down L

If you insert a node in time to join the binary tree, is mounted in the lower right child node of his grandfather, and is the right child of its parent node, and cause the entire binary tree balanced, so at this time we use a left-handed way, to binary sort tree adjustment, namely: the right down left and right

Step L:
Step 1: the position of the parent node substituted grandparent, i.e. lifted up one
Step 2: grandfather left child node becomes the parent node, a parent node can not exist at this time left child node, because if present, in the last round should have been balanced by turning the adjustment
step 3: the relationship between the remaining nodes remains unchanged

(3) about a spin down about

Step about spin:
Step 1: the insertion node unsubstituted parent node location
Step 2: Insert node after the parent node becomes the alternative left child node
Step 3: After replacing the insertion node replacement grandparent
Step 4: grandparent be inserted after replacement right child nodes of
5 steps: the relationship between the remaining nodes remains unchanged

(4) Right Left Right down the left

If you insert a node in time to join the binary tree, is mounted in the lower right child node of his grandfather, and is the left child of its parent node, and cause the entire binary tree balanced, so at this time we use left-handed and right way, binary sort tree to be adjusted, namely: right and left down left and right

右左旋的步骤:
步骤1:插入节点取代父节点的位置
步骤2:父节点成为替换后插入节点的右孩子节点
步骤3:替换后的插入节点替换祖父节点
步骤4:祖父节点成为替换后的插入节点的左孩子节点
步骤5:其余节点之间的关系保持不变

2.2、四代以内添加节点的情况

四代以内的情况,一般来讲都指的是曾祖节点因为元素的插入导致不平衡四代以内的情况我们可以分为如下4种:

(1)左左型右旋

第1个左:曾祖节点的左子树深度高于右子树深度,那么说明问题出现在曾祖节点的左子树中
第2个左:曾祖节点左孩子的左子树深度高于曾祖节点左孩子的右子树深度,说明问题出在曾祖节点左孩子的左子树中,此时我们通过右旋解决这一问题。

右旋步骤:
步骤1:使用插入节点的祖父节点替代插入节点的曾祖节点
步骤2:曾祖节点连同其右孩子一起成为祖父节点的右孩子
步骤3:祖父节点原先的右孩子成为曾祖节点的左孩子
步骤4:其余节点之间的关系保持不变

(2)右右型左旋

第1个右:曾祖节点的右子树深度高于左子树深度,那么说明问题出现在曾祖节点的右子树中
第2个右:曾祖节点右孩子的右子树深度高于曾祖节点右孩子的左子树深度,说明问题出在曾祖节点右孩子的右子树中
此时我们通过左旋解决这一问题。

左旋步骤:
步骤1:使用插入节点的祖父节点替代插入节点的曾祖节点
步骤2:曾祖节点连同其左孩子一起成为祖父节点的左孩子
步骤3:祖父节点原先的左孩子成为曾祖节点的右孩子
步骤4:其余节点之间的关系保持不变

(3)左右型左右旋

第1个左:曾祖节点的左子树深度高于右子树深度,那么说明问题出现在曾祖节点的左子树中

第2个右:曾祖节点左孩子的右子树深度高于曾祖节点左孩子的左子树深度,说明问题出在曾祖节点左孩子的右子树中
此时我们通过左右旋解决这一问题

左右旋的步骤:
步骤1:使用父节点替代祖父节点
步骤2:祖父节点成为父节点的左孩子;
             如果父节点原先只有左孩子,则父节点的左孩子变成祖父节点的右孩子;
             如果父节点原先只有右孩子,则右孩子位置不变;祖父节点左旋完成
             注意:父节点不可能同时具有左孩子和右孩子
步骤3:祖父节点左旋完毕后,使用新的祖父节点替代曾祖节点,曾祖节点及其右孩子成为祖父节
点的右孩子,曾祖节点右旋完成
步骤4:其余节点之间的关系保持不变

(4)右左型右左旋

第1个右:曾祖节点的右子树深度高于左子树深度,那么说明问题出现在曾祖节点的右子树中
第2个左:曾祖节点右孩子的左子树深度高于曾祖节点右孩子的右子树深度,说明问题出在曾祖节点右孩子的左子树中此时我们通过右左旋解决这一问题

右左旋的步骤:
步骤1:使用父节点替代祖父节点
步骤2:祖父节点成为父节点的右孩子;
             如果父节点原先只有左孩子,则左孩子位置不变;
             如果父节点原先只有右孩子,则父节点的右孩子变成祖父节点的左孩子;祖父节点右旋完成
             注意:父节点不可能同时具有左孩子和右孩子
步骤3:祖父节点右旋完毕后,使用新的祖父节点替代曾祖节,曾祖节点及其左孩子成为祖父节点的左孩子,曾祖节点左旋完成
步骤4:其余节点之间的关系保持不变

3.1、不影响平衡性的的删除

假设我们在删除AVL树的一个节点之后,整个AVL树依然是平衡的,那么我们可以根据删除节点的子节点数量,更加详细的分出如下3种情况:
(1)删除的是叶子节点

如果删除的是一个叶子节点,并且在删除之后整个AVL树依然处于平衡状态,那么次数没有必要对AVL树结构做出任何调整,直接删除这个节点即可。

(2)删除带有一个子节点的节点
如果我们删除的节点带有一个子节点,并且在删除这个节点之后,整个AVL树结构依然保持平衡,那么不论这个节点的子节点是其左孩子还是其右孩子,只要使用这个节点的子节点替换这个节点原有的位置即可,此时依然不需要对整个AVL树结构做出任何调整。

(3)删除带有两个子节点的节点
在这种情况下,我们选择使用当前AVL树中,比删除节点大的节点中,取值最小的节点,来替换删除节点,而这种节点,我们称之为后继节点,如下图中的节点7,就是删除节点6的后继节点:

如果我们删除节点2,那么节点3就是删除节点2的后继节点,并使用节点3来替换节点2,可是如果后继节点同样具有左右孩子怎么办?那么此时我们就如同对待删除节点一样,对待这个后继节点,就好像后继节点被删除了一样。上面我们讨论的都是在删除节点后,AVL树依然能够保持平衡的情况,下面我们一起来讨论下,在删除节点之后,AVL如果不能够继续保持平衡,应该如何进行调整。同样,我们需要分别讨论不平衡节点在3代以内和4代以内的两种大情况

3.2、三代以内删除节点的操作

三代以内的情况,一般来讲都指的是祖父节点因为元素的删除导致不平衡,三代以内的情况我们可以分为如下4种:

(1)左左高的右旋

第1个左:删除节点之后,如果祖父节点的左子树深度大于右子树深度,说明问题出在祖父节点的左子树上
第2个左:祖父节点左孩子的左子树深度大于等于祖父节点左孩子右子树的深度,那么说明只要对祖父节点进行右旋就能够保证AVL树的平衡,此时我们通过右旋解决这一问题

右旋的步骤:
步骤1:使用父节点替换祖父节点
步骤2:如果父节点原先就具有右孩子,那么父节点的右孩子变成祖父节点的左孩子
步骤3:其余节点之间的关系保持不变

(2)右右高的左旋

第1个右:删除节点之后,如果祖父节点的右子树深度大于左子树深度,说明问题出在祖父节点的右子树上
第2个左:祖父节点右孩子的右子树深度大于等于祖父节点右孩子左子树的深度,那么说明只要对祖父节点进行左旋就能够保证AVL树的平衡,此时我们通过左旋解决这一问题

左旋的步骤:
步骤1:使用父节点替换祖父节点
步骤2:如果父节点原先就具有左孩子,那么父节点的左孩子变成祖父节点的右孩子
步骤3:其余节点之间的关系保持不变
(3)左右高的左右旋
第1个左:删除节点之后,如果祖父节点的左子树深度大于右子树深度,说明问题出在祖父节点的左子树上
第2个右:祖父节点左孩子的右子树深度大于祖父节点左孩子左子树的深度,那么说明只要对祖父节点进行左右旋就能够保证AVL树的平衡,此时我们通过左右旋解决这一问题

左右旋的步骤:
步骤1:使用叶子节点替换父节点,父节点完成左旋
步骤2:使用替换后的父节点替换祖父节点,祖父节点成为父节点的右孩子,祖父节点右旋完成
步骤3:其余节点之间的关系保持不变
(4) 右左高的右左旋
第1个右:删除节点之后,如果祖父节点的右子树深度大于左子树深度,说明问题出在祖父节点的右子树上
第2个左:祖父节点右孩子的左子树深度大于祖父节点右孩子右子树的深度,那么说明只要对祖父节点进行右左旋就能够保证AVL树的平衡,此时我们通过右左旋解决这一问题

右左旋的步骤:
步骤1:使用叶子节点替换父节点,父节点完成右旋
步骤2:使用替换后的父节点替换祖父节点,祖父节点成为父节点的左孩子,祖父节点左旋完成
步骤3:其余节点之间的关系保持不变

3.3、四代以内删除节点的情况

四代以内的情况,一般来讲都指的是曾祖节点因为元素的删除导致不平衡。四代以内的情况我们可以分为如下4种:

(1)左左型右旋

第1个左:在删除节点后,曾祖节点的左子树深度大于右子树深度,说明问题出在曾祖节点的左子树上
第2个左:曾祖节点左孩子的左子树深度大于等于曾祖节点左孩子右子树的深度,说明问题出在曾祖节点左孩子的左子树上
此时我们通过右旋解决这一问题

右旋的步骤:
步骤1:使用祖父节点替换曾祖节点
步骤2:祖父节点原来的右孩子变成祖父节点的左孩子
步骤3:其余节点之间的关系保持不变

(2)右右型左旋

第1个右:在删除节点后,曾祖节点的右子树深度大于左子树深度,说明问题出在曾祖节点的右子树上
第2个右:曾祖节点右孩子的右子树深度大于等于曾祖节点右孩子左子树的深度,说明问题出在曾祖节点右孩子的右子树上,此时我们通过左旋解决这一问题

左旋的步骤:
步骤1:使用祖父节点替换曾祖节点
步骤2:祖父节点原来的左孩子变成祖父节点的右孩子
步骤3:其余节点之间的关系保持不变

(3)左右型左右旋

第1个左:在删除节点后,曾祖节点的左子树深度大于右子树深度,说明问题出在曾祖节点的左子树上
第2个右:曾祖节点左孩子的右子树深度大于曾祖节点左孩子左子树的深度,说明问题出在曾祖节点左孩子的右子树上
此时我们通过左右旋解决这一问题

左右旋的步骤:
步骤1:父节点替代祖父节点,父节点原来的左孩子变成祖父节点的右孩子,祖父节点完成左旋
步骤2:祖父节点替代曾祖节点,祖父节点原来的右孩子变成曾祖节点的左孩子,曾祖节点完成右旋
步骤3:其余节点之间的关系保持不变

(4)右左型右左旋

第1个右:在删除节点后,曾祖节点的右子树深度大于左子树深度,说明问题出在曾祖节点的右子树上
第2个左:曾祖节点右孩子的左子树深度大于曾祖节点右孩子右子树的深度,说明问题出在曾祖节点右孩子的左子树上,此时我们通过右左旋解决这一问题

右左旋的步骤:
步骤1:父节点替代祖父节点,父节点原来的右孩子变成祖父节点的左孩子,祖父节点完成右旋
步骤2:祖父节点替代曾祖节点,祖父节点原来的左孩子变成曾祖节点的右孩子,曾祖节点完成左旋
步骤3:其余节点之间的关系保持不变

四、总结

在看了上面那么多令人头晕眼花的案例之后,我们静下心来,仔细想想,实际上我们需要掌握的旋转方式只有4中:左旋、右旋、左右旋、右左旋。而将这四种旋转方式与能够处理的问题总结在一张表中,可以得到如下结果:

所以从上表我们不难总结出对AVL树进行旋转的方式:左左不平右旋、右右不平左旋,左右不平左右旋,右左不平右左旋。
上面总结的结果,不论是在涉及到3代节点还是4代节点之间的关系、不论是在插入节点的情况下还是删除节点的情况下,都是完全成立的。

 

 

 

 

 

 

 

 

 

 

 

 

发布了98 篇原创文章 · 获赞 165 · 访问量 21万+

Guess you like

Origin blog.csdn.net/cyl101816/article/details/99313704