• Python与数据结构[3] -> 树/Tree[2] -> AVL 平衡树和树旋转的 Python 实现


    AVL 平衡树和树旋转


    目录

    1. AVL平衡二叉树
    2. 树旋转
    3. 代码实现

    1 AVL平衡二叉树

    AVL(Adelson-Velskii & Landis)树是一种带有平衡条件的二叉树,一棵AVL树其实是一棵左子树和右子树高度最多差1的二叉查找树。一棵树的不平衡主要是由于插入和删除的过程中产生的,此时则需要使用旋转来对AVL树进行平衡。

    AVL Tree:
                    0 
               _____|_____
              |           |
              0           0 
              |___     ___|___
                  |   |       |
                  0   0       0 
                              |__
                                 |
                                 0 

    插入引起不平衡主要有以下四种情况:

    Insert unbalance:
        1:             |  2:           |  3:            | 4:
               A(2)    |        A(2)   |       A(2)     |    A(2)             
             __|       |      __|      |       |__      |    |__        
            |          |     |         |          |     |       |           
            B(1)       |     B(1)      |          B(1)  |       B(1)        
          __|          |     |__       |        __|     |       |__         
         |             |        |      |       |        |          |        
        ----           |       ----    |      ----      |         ----     
       |X(0)|          |      |X(0)|   |     |X(0)|     |        |X(0)|    
        ----           |       ----    |      ----      |         ----     

    删除引起不平衡主要有以下四种情况:

    Delete unbalance:
        1:             |  2:           |  3:            |  4:
               A(2)    |      A(2)     |        A(2)    |       A(2)        
             __|__     |    __|__      |      __|__     |     __|__        
            |     |    |   |     |     |     |     |    |    |     |            
            B(1) ----  |   B(1)  ----  |  ----     B(1) |  ----    B(1)          
          __|   |X(0)| |   |__  |X(0)| | |X(0)|  __|    | |X(0)|   |__            
         |       ----  |      |  ----  |  ----  |       |  ----       |          
         C(0)          |      C(0)     |        C(0)    |             C(0)

    2. 树旋转

    对于上面的不平衡情况,可以分别采用以下的树旋转方式解决,

    2.1 向左单旋转

    适用于处理上面插入/删除引起的不平衡情况1,

    下图中K2两个子树节点相差高度等于2,产生了不平衡,因此需要使用单旋转处理,

    在向左单旋转时,若K1有右子树,则转变为K2的左子树。

                     K2(2)                      K1(1)
                   __|__                      ____|_____
                  |     |                    |          |
                  K1(1) None(-1)  -------->  X(0)       K2(1)
                __|__                                 __|__
               |     |                               |     |
               X(0)  Y(0)                            Y(0)  None(-1)

    2.2 向右单旋转

    适用于处理上面插入/删除引起的不平衡情况4,

    在向右单旋转时,若K1有左子树,则转变为K2的右子树。

                     K2(2)                      K1(2)
                   __|__                      ____|_____
                  |     |                    |          |
              (-1)None  K1(1)   -------->    K2(1)      Y(0)
                      __|__                __|__
                     |     |              |     |
                     X(0)  Y(0)       (-1)None  X(0)

    2.3 右左双旋转

    适用于处理上面插入/删除引起的不平衡情况2,

    首先对K1进行一次向右单旋转,再对K3进行一次向左单旋转,

                     K3(3)                     K3(3)                     K2(2)  
                   __|__                     __|__                  _____|_____ 
                  |     |      right        |     |      left      |           |   
                  K1(2) D(0)  -------->     K2(2) D(0) -------->   K1(1)       K3(1)
                __|__                     __|__                  __|__       __|__ 
               |     |                   |     |                |     |     |     |        
               A(0)  K2(1)               K1(1) C(0)             A(0)  B(0) C(0)  D(0)    
                   __|__               __|__                   
                  |     |             |     |                  
                  B(0)  C(0)          A(0)  B(0)         

    2.4 左右双旋转

    适用于处理上面插入/删除引起的不平衡情况3,

    首先对K1进行一次向左单旋转,再对K3进行一次向右单旋转,

                     K3(3)                     K3(3)                     K2(2)  
                   __|__                     __|__                  _____|_____ 
                  |     |         left      |     |       right    |           |   
                  D(0)  K1(2)   -------->   D(0)  K2(2) -------->  K3(1)       K1(1)
                      __|__                     __|__            __|__       __|__ 
                     |     |                   |     |          |     |     |     |        
                     K2(1) A(0)                C(0)  K1(1)      D(0)  C(0)  B(0)  A(0)    
                   __|__                           __|__                   
                  |     |                         |     |                  
                  C(0)  B(0)                      B(0)  A(0)         

    3 Python代码实现

    下面利用Python实现AVL树,以及树的旋转操作,

    完整代码

      1 from search_tree import SearchTree
      2 
      3 
      4 class AvlNode:
      5     def __init__(self, val=None, lef=None, rgt=None, hgt=0):
      6         self.value = val
      7         self.left = lef
      8         self.right = rgt
      9         self.height = hgt
     10 
     11     def __str__(self):
     12         return str(self.value)
     13 
     14 
     15 class AvlTree(SearchTree):
     16     """
     17     AVL Tree:
     18                 0 
     19            _____|_____
     20           |           |
     21           0           0 
     22           |___     ___|___
     23               |   |       |
     24               0   0       0 
     25                           |__
     26                              |
     27                              0 
     28     Insert unbalance:
     29     1:             |  2:           |  3:            | 4:
     30            A(2)    |        A(2)   |       A(2)     |    A(2)             
     31          __|       |      __|      |       |__      |    |__        
     32         |          |     |         |          |     |       |           
     33         B(1)       |     B(1)      |          B(1)  |       B(1)        
     34       __|          |     |__       |        __|     |       |__         
     35      |             |        |      |       |        |          |        
     36     ----           |       ----    |      ----      |         ----     
     37    |X(0)|          |      |X(0)|   |     |X(0)|     |        |X(0)|    
     38     ----           |       ----    |      ----      |         ----         
     39 
     40     Delete unbalance:
     41     1:             |  2:           |  3:            |  4:
     42            A(2)    |      A(2)     |        A(2)    |       A(2)        
     43          __|__     |    __|__      |      __|__     |     __|__        
     44         |     |    |   |     |     |     |     |    |    |     |            
     45         B(1) ----  |   B(1)  ----  |  ----     B(1) |  ----    B(1)          
     46       __|   |X(0)| |   |__  |X(0)| | |X(0)|  __|    | |X(0)|   |__            
     47      |       ----  |      |  ----  |  ----  |       |  ----       |          
     48      C(0)          |      C(0)     |        C(0)    |             C(0)
     49     """                                                
     50     def get_height(self, node):
     51         if isinstance(node, AvlNode):
     52             return node.height
     53         return -1
     54 
     55     def single_rotate_left(self, k2):
     56         """
     57                  K2(2)                      K1(1)
     58                __|__                      ____|_____
     59               |     |                    |          |
     60               K1(1) None(-1)  -------->  X(0)       K2(1)
     61             __|__                                 __|__
     62            |     |                               |     |
     63            X(0)  Y(0)                            Y(0)  None(-1)
     64         """
     65         # Left rotate
     66         k1 = k2.left
     67         k2.left = k1.right
     68         k1.right = k2
     69         # Update height
     70         k2.height = max(self.get_height(k2.left), self.get_height(k2.right)) + 1
     71         k1.height = max(self.get_height(k1.left), k2.height) + 1
     72         return k1
     73 
     74     def single_rotate_right(self, k2):
     75         """
     76                  K2(2)                      K1(2)
     77                __|__                      ____|_____
     78               |     |                    |          |
     79           (-1)None  K1(1)   -------->    K2(1)      Y(0)
     80                   __|__                __|__
     81                  |     |              |     |
     82                  X(0)  Y(0)       (-1)None  X(0)
     83         """
     84         # Right rotate
     85         k1 = k2.right
     86         k2.right = k1.left
     87         k1.left = k2
     88         # Update height
     89         k2.height = max(self.get_height(k2.left), self.get_height(k2.right)) + 1
     90         k1.height = max(k2.height, self.get_height(k1.right)) + 1
     91         return k1
     92 
     93     def double_rotate_left(self, k3):   
     94         """
     95                  K3(3)                     K3(3)                     K2(2)  
     96                __|__                     __|__                  _____|_____ 
     97               |     |      right        |     |      left      |           |   
     98               K1(2) D(0)  -------->     K2(2) D(0) -------->   K1(1)       K3(1)
     99             __|__                     __|__                  __|__       __|__ 
    100            |     |                   |     |                |     |     |     |        
    101            A(0)  K2(1)               K1(1) C(0)             A(0)  B(0) C(0)  D(0)    
    102                __|__               __|__                   
    103               |     |             |     |                  
    104               B(0)  C(0)          A(0)  B(0)               
    105         """
    106         # Rotate between k1 and k2
    107         k3.left = self.single_rotate_right(k3.left)
    108         # Rotate between k3 and k2
    109         return self.single_rotate_left(k3)
    110 
    111     def double_rotate_right(self, k3):
    112         """
    113                  K3(3)                     K3(3)                     K2(2)  
    114                __|__                     __|__                  _____|_____ 
    115               |     |         left      |     |       right    |           |   
    116               D(0)  K1(2)   -------->   D(0)  K2(2) -------->  K3(1)       K1(1)
    117                   __|__                     __|__            __|__       __|__ 
    118                  |     |                   |     |          |     |     |     |        
    119                  K2(1) A(0)                C(0)  K1(1)      D(0)  C(0)  B(0)  A(0)    
    120                __|__                           __|__                   
    121               |     |                         |     |                  
    122               C(0)  B(0)                      B(0)  A(0)               
    123         """
    124         # Rotate between k1 and k2
    125         k3.right = self.single_rotate_left(k3.right)
    126         # Rotate between k3 and k2
    127         return self.single_rotate_right(k3)
    128 
    129     def insert(self, item):
    130         if self._root is None:
    131             self._root = AvlNode(item)
    132             return
    133         
    134         def _insert(item, node):
    135             if not node:
    136                 return AvlNode(item)
    137             if item < node.value:
    138                 node.left = _insert(item, node.left)
    139                 if self.get_height(node.left) - self.get_height(node.right) == 2:
    140                     if item < node.left.value:      # Situation 1: left --> left
    141                         node = self.single_rotate_left(node)
    142                     else:                           # Situation 2: left --> right
    143                         node = self.double_rotate_left(node)
    144             elif item > node.value:
    145                 node.right = _insert(item, node.right)
    146                 if self.get_height(node.right) - self.get_height(node.left) == 2:
    147                     if item < node.right.value:     # Situation 3: right --> left
    148                         node = self.double_rotate_right(node)
    149                     else:                           # Situation 4: right --> right
    150                         node = self.single_rotate_right(node)
    151             else: pass
    152             # Update node height (if not rotated, update is necessary.)
    153             node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
    154             return node
    155         self._root = _insert(item, self._root)
    156 
    157     def delete(self, item):
    158         if self._root is None:
    159             return
    160 
    161         def _delete(item, node):
    162             if not node:    # Node no found
    163                 # return None
    164                 raise Exception('Element not in tree.')
    165 
    166             if item < node.value:
    167                 node.left = _delete(item, node.left)
    168                 # Delete left, rotate right
    169                 if self.get_height(node.right) - self.get_height(node.left) == 2:
    170                     if self.get_height(node.right.right) >= self.get_height(node.right.left):   # Situation 4
    171                         node = self.single_rotate_right(node)
    172                     else:                                                                       # Situation 3
    173                         node = self.double_rotate_right(node)
    174 
    175             elif item > node.value:
    176                 node.right = _delete(item, node.right)
    177                 # Delete right, rotate left
    178                 if self.get_height(node.left) - self.get_height(node.right) == 2:
    179                     if self.get_height(node.left.left) >= self.get_height(node.left.right):     # Situation 1
    180                         node = self.single_rotate_left(node)
    181                     else:                                                                       # Situation 3
    182                         node = self.double_rotate_left(node)
    183 
    184             else:   # Node found
    185                 if node.left and node.right:
    186                     # Minimum node in right sub-tree has no left sub-node, can be used to make replacement
    187                     # Find minimum node in right sub-tree
    188                     min_node = self.find_min(node.right)    
    189                     # Replace current node with min_node
    190                     node.value = min_node.value
    191                     # Delete min_node in right sub-tree
    192                     node.right = _delete(min_node.value, node.right)
    193                 else:
    194                     if node.left: 
    195                         node = node.left
    196                     elif node.right:
    197                         node = node.right
    198                     else:
    199                         node = None
    200             # Update node height (if not ratated, update is necessary.)
    201             # If node is None, height is -1 already.
    202             if node:
    203                 node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
    204             return node
    205         self._root = _delete(item, self._root)
    206 
    207                  
    208 def test(avl):
    209     print('
    Init an AVL tree:')
    210     for i in [1, 2, 3, 4, 5, 6, 7]:
    211         avl.insert(i)
    212     avl.show()
    213 
    214     print('
    Left single rotate:')
    215     avl.delete(5)
    216     avl.delete(7)
    217     avl.delete(6)
    218     avl.show()
    219 
    220     avl.make_empty()
    221     print('
    Init an AVL tree:')
    222     for i in [1, 2, 3, 4, 5, 6, 7]:
    223         avl.insert(i)
    224     
    225     print('
    Right single rotate:')
    226     avl.delete(1)
    227     avl.delete(3)
    228     avl.delete(2)
    229     avl.show()
    230 
    231     avl.make_empty()
    232     print('
    Init an AVL tree:')
    233     for i in [6, 2, 8, 1, 4, 9, 3, 5]:
    234         avl.insert(i)
    235     avl.show()
    236 
    237     print('
    Right-Left double rotate:')
    238     avl.delete(9)
    239     avl.show()
    240 
    241     avl.make_empty()
    242     print('
    Init an AVL tree:')
    243     for i in [4, 2, 8, 1, 6, 9, 5, 7]:
    244         avl.insert(i)
    245     avl.show()
    246 
    247     print('
    Left-Right double rotate:')
    248     avl.delete(1)
    249     avl.show()
    250 
    251 if __name__ == '__main__':
    252     test(AvlTree())
    View Code

    分段解释

    首先,需要导入查找树,以及定义AVL树的节点,

     1 from search_tree import SearchTree
     2 
     3 
     4 class AvlNode:
     5     def __init__(self, val=None, lef=None, rgt=None, hgt=0):
     6         self.value = val
     7         self.left = lef
     8         self.right = rgt
     9         self.height = hgt
    10 
    11     def __str__(self):
    12         return str(self.value)

    接着构建一棵AVL树的类,构造方法可继承查找树,

     1 class AvlTree(SearchTree):
     2     """
     3     AVL Tree:
     4                 0 
     5            _____|_____
     6           |           |
     7           0           0 
     8           |___     ___|___
     9               |   |       |
    10               0   0       0 
    11                           |__
    12                              |
    13                              0 
    14     Insert unbalance:
    15     1:             |  2:           |  3:            | 4:
    16            A(2)    |        A(2)   |       A(2)     |    A(2)             
    17          __|       |      __|      |       |__      |    |__        
    18         |          |     |         |          |     |       |           
    19         B(1)       |     B(1)      |          B(1)  |       B(1)        
    20       __|          |     |__       |        __|     |       |__         
    21      |             |        |      |       |        |          |        
    22     ----           |       ----    |      ----      |         ----     
    23    |X(0)|          |      |X(0)|   |     |X(0)|     |        |X(0)|    
    24     ----           |       ----    |      ----      |         ----         
    25 
    26     Delete unbalance:
    27     1:             |  2:           |  3:            |  4:
    28            A(2)    |      A(2)     |        A(2)    |       A(2)        
    29          __|__     |    __|__      |      __|__     |     __|__        
    30         |     |    |   |     |     |     |     |    |    |     |            
    31         B(1) ----  |   B(1)  ----  |  ----     B(1) |  ----    B(1)          
    32       __|   |X(0)| |   |__  |X(0)| | |X(0)|  __|    | |X(0)|   |__            
    33      |       ----  |      |  ----  |  ----  |       |  ----       |          
    34      C(0)          |      C(0)     |        C(0)    |             C(0)
    35     """                                                
    

    定义获取节点子树高度的方法,当节点为None时,返回高度为-1,

    1     def get_height(self, node):
    2         if isinstance(node, AvlNode):
    3             return node.height
    4         return -1

    定义向左的单旋转方法,旋转完成后更新高度

     1     def single_rotate_left(self, k2):
     2         """
     3                  K2(2)                      K1(1)
     4                __|__                      ____|_____
     5               |     |                    |          |
     6               K1(1) None(-1)  -------->  X(0)       K2(1)
     7             __|__                                 __|__
     8            |     |                               |     |
     9            X(0)  Y(0)                            Y(0)  None(-1)
    10         """
    11         # Left rotate
    12         k1 = k2.left
    13         k2.left = k1.right
    14         k1.right = k2
    15         # Update height
    16         k2.height = max(self.get_height(k2.left), self.get_height(k2.right)) + 1
    17         k1.height = max(self.get_height(k1.left), k2.height) + 1
    18         return k1

    定义向右的单旋转方法,旋转完成后更新高度

     1     def single_rotate_right(self, k2):
     2         """
     3                  K2(2)                      K1(2)
     4                __|__                      ____|_____
     5               |     |                    |          |
     6           (-1)None  K1(1)   -------->    K2(1)      Y(0)
     7                   __|__                __|__
     8                  |     |              |     |
     9                  X(0)  Y(0)       (-1)None  X(0)
    10         """
    11         # Right rotate
    12         k1 = k2.right
    13         k2.right = k1.left
    14         k1.left = k2
    15         # Update height
    16         k2.height = max(self.get_height(k2.left), self.get_height(k2.right)) + 1
    17         k1.height = max(k2.height, self.get_height(k1.right)) + 1
    18         return k1

    定义先右后左的双旋转方法,旋转完成后更新高度

     1     def double_rotate_left(self, k3):   
     2         """
     3                  K3(3)                     K3(3)                     K2(2)  
     4                __|__                     __|__                  _____|_____ 
     5               |     |      right        |     |      left      |           |   
     6               K1(2) D(0)  -------->     K2(2) D(0) -------->   K1(1)       K3(1)
     7             __|__                     __|__                  __|__       __|__ 
     8            |     |                   |     |                |     |     |     |        
     9            A(0)  K2(1)               K1(1) C(0)             A(0)  B(0) C(0)  D(0)    
    10                __|__               __|__                   
    11               |     |             |     |                  
    12               B(0)  C(0)          A(0)  B(0)               
    13         """
    14         # Rotate between k1 and k2
    15         k3.left = self.single_rotate_right(k3.left)
    16         # Rotate between k3 and k2
    17         return self.single_rotate_left(k3)

    定义先左后右的双旋转方法,旋转完成后更新高度

     1     def double_rotate_right(self, k3):
     2         """
     3                  K3(3)                     K3(3)                     K2(2)  
     4                __|__                     __|__                  _____|_____ 
     5               |     |         left      |     |       right    |           |   
     6               D(0)  K1(2)   -------->   D(0)  K2(2) -------->  K3(1)       K1(1)
     7                   __|__                     __|__            __|__       __|__ 
     8                  |     |                   |     |          |     |     |     |        
     9                  K2(1) A(0)                C(0)  K1(1)      D(0)  C(0)  B(0)  A(0)    
    10                __|__                           __|__                   
    11               |     |                         |     |                  
    12               C(0)  B(0)                      B(0)  A(0)               
    13         """
    14         # Rotate between k1 and k2
    15         k3.right = self.single_rotate_left(k3.right)
    16         # Rotate between k3 and k2
    17         return self.single_rotate_right(k3)

    定义插入方法,进行递归插入,每次插入后都需要检测子树高度来决定是否需要对树进行平衡旋转,最后进行高度更新,若经过旋转则此时高度已经被更新。

     1     def insert(self, item):
     2         if self._root is None:
     3             self._root = AvlNode(item)
     4             return
     5         
     6         def _insert(item, node):
     7             if not node:
     8                 return AvlNode(item)
     9             if item < node.value:
    10                 node.left = _insert(item, node.left)
    11                 if self.get_height(node.left) - self.get_height(node.right) == 2:
    12                     if item < node.left.value:      # Situation 1: left --> left
    13                         node = self.single_rotate_left(node)
    14                     else:                           # Situation 2: left --> right
    15                         node = self.double_rotate_left(node)
    16             elif item > node.value:
    17                 node.right = _insert(item, node.right)
    18                 if self.get_height(node.right) - self.get_height(node.left) == 2:
    19                     if item < node.right.value:     # Situation 3: right --> left
    20                         node = self.double_rotate_right(node)
    21                     else:                           # Situation 4: right --> right
    22                         node = self.single_rotate_right(node)
    23             else: pass
    24             # Update node height (if not rotated, update is necessary.)
    25             node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
    26             return node
    27         self._root = _insert(item, self._root)

    定义删除方法,进行递归删除,删除后检测是否需要平衡旋转,并选择旋转的方式,删除完成根据需要进行高度更新。

     1     def delete(self, item):
     2         if self._root is None:
     3             return
     4 
     5         def _delete(item, node):
     6             if not node:    # Node no found
     7                 # return None
     8                 raise Exception('Element not in tree.')
     9 
    10             if item < node.value:
    11                 node.left = _delete(item, node.left)
    12                 # Delete left, rotate right
    13                 if self.get_height(node.right) - self.get_height(node.left) == 2:
    14                     if self.get_height(node.right.right) >= self.get_height(node.right.left):   # Situation 4
    15                         node = self.single_rotate_right(node)
    16                     else:                                                                       # Situation 3
    17                         node = self.double_rotate_right(node)
    18 
    19             elif item > node.value:
    20                 node.right = _delete(item, node.right)
    21                 # Delete right, rotate left
    22                 if self.get_height(node.left) - self.get_height(node.right) == 2:
    23                     if self.get_height(node.left.left) >= self.get_height(node.left.right):     # Situation 1
    24                         node = self.single_rotate_left(node)
    25                     else:                                                                       # Situation 3
    26                         node = self.double_rotate_left(node)
    27 
    28             else:   # Node found
    29                 if node.left and node.right:
    30                     # Minimum node in right sub-tree has no left sub-node, can be used to make replacement
    31                     # Find minimum node in right sub-tree
    32                     min_node = self.find_min(node.right)    
    33                     # Replace current node with min_node
    34                     node.value = min_node.value
    35                     # Delete min_node in right sub-tree
    36                     node.right = _delete(min_node.value, node.right)
    37                 else:
    38                     if node.left: 
    39                         node = node.left
    40                     elif node.right:
    41                         node = node.right
    42                     else:
    43                         node = None
    44             # Update node height (if not ratated, update is necessary.)
    45             # If node is None, height is -1 already.
    46             if node:
    47                 node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
    48             return node
    49         self._root = _delete(item, self._root)

    最后定义一个测试函数,用于测试AVL树的功能。

    首先初始化一棵树

    1 def test(avl):
    2     print('
    Init an AVL tree:')
    3     for i in [1, 2, 3, 4, 5, 6, 7]:
    4         avl.insert(i)
    5     avl.show()

    得到结果

    Init an AVL tree:
    4            |          4  
        2        |        __|__     
            1    |       |     |    
            3    |       2     6
        6        |      _|_   _|_         
            5    |     |   | |   |         
            7    |     1   3 5   7

    接着尝试删除5, 6, 7三个节点,完成一个向左单旋转,

    1     print('
    Left single rotate:')
    2     avl.delete(5)
    3     avl.delete(7)
    4     avl.delete(6)
    5     avl.show()

    得到结果,可以看到,此时AVL树已经完成了一个向左的平衡旋转

    Left single rotate:
    2           |       2  
        1       |     __|__ 
        4       |    |     |
            3   |    1     4
                |         _|  
                |        | 
                |        3    

    清空树并再次初始化树后

    尝试删除1, 2, 3三个节点,完成一个向右单旋转,

    1     print('
    Delete element from tree:')
    2     avl.delete(1)
    3     avl.delete(3)
    4     avl.delete(2)
    5     avl.show()

    得到结果,可以看到,此时AVL树已经完成了一个向右的平衡旋转

    Delete element from tree:
    6           |       6  
        4       |     __|__   
            5   |    |     |  
        7       |    4     7
                |    |_  
                |      | 
                |      5 

     再次清空树,并建立一棵新的树

    1     avl.make_empty()
    2     print('
    Init an AVL tree:')
    3     for i in [6, 2, 8, 1, 4, 9, 3, 5]:
    4         avl.insert(i)
    5     avl.show()

    得到结果

    Init an AVL tree:
    6              |       6  
        2          |     __|__ 
            1      |    |     |
            4      |    2     8
                3  |   _|_    |_
                5  |  |   |     |
        8          |  1   4     9
            9      |     _|_ 
                   |    |   |
                   |    3   5

    此时尝试删除节点9,完成一个右左双旋转

    1     print('
    Right-Left double rotate:')
    2     avl.delete(9)
    3     avl.show()

    得到结果

    Right-Left double rotate:
    4           |       4  
        2       |     __|__ 
            1   |    |     |
            3   |    2     6
        6       |   _|_   _|_
            5   |  |   | |   |
            8   |  1   3 5   8

    最后再次清空树建立一棵新树,

    1     avl.make_empty()
    2     print('
    Init an AVL tree:')
    3     for i in [4, 2, 8, 1, 6, 9, 5, 7]:
    4         avl.insert(i)
    5     avl.show()

    显示结果如下

    Init an AVL tree:
    4              |       4      
        2          |     __|__ 
            1      |    |     |
        8          |    2     8
            6      |   _|    _|_
                5  |  |     |   |
                7  |  1     6   9
            9      |       _|_ 
                   |      |   |
                   |      5   7  

    此时尝试删除节点1,造成不平衡完成一个左右双旋转

    1     print('
    Left-Right double rotate:')
    2     avl.delete(1)
    3     avl.show()

    得到结果

    Left-Right double rotate:
    6           |       6       
        4       |     __|__ 
            2   |    |     |
            5   |    4     8
        8       |   _|_   _|_
            7   |  |   | |   |
            9   |  2   5 7   9

    相关阅读


    1. 二叉树

    2. 查找树

  • 相关阅读:
    [转]iOS框架和服务
    [Tips]统计Xcode代码行数
    [转]10个迷惑新手的Cocoa,Objective-c开发难点和问题
    关于 MRC 开发中的一些细节
    关于HTTP状态码的说明
    关于 MRC下自动释放池 的嵌套使用的几个问题
    C语言综合运用-------------编写 < 通讯录 >
    FFT与游戏开发(二)
    FFT与游戏开发(一)
    FFT开坑
  • 原文地址:https://www.cnblogs.com/stacklike/p/8290070.html
Copyright © 2020-2023  润新知