AVL树:AVL树是一棵自平衡的二叉搜索树
    AVL树具有与以下性质:
    根的左右子树高度差的绝对值不超过1
    根的左右子树都是平衡二叉树

    image.png

    image.png
    插入一个节点可能会破坏AVL树的平衡,可以通过旋转操作来进行修正。
    插入一个节点后,只有从插入节点到根节点的路径上的节点平衡可能被改变。我们需要找出第一个破坏了平衡条件的节点,称之为K。K的两颗子树的高度查2。
    不平衡的出现可能有4中情况。
    旋转口诀:
    对于K,右右->左旋,左左->右旋,右左->右左,左右->左右

    IMG_0616.PNGIMG_0618.PNGIMG_0619.PNGIMG_0620.PNG

    1、需引用二叉搜索树

    1. # -*- encoding= utf-8 -*-
    2. from bst_new import BiTreeNode,BST
    3. class AVLNode(BiTreeNode):
    4. def __init__(self,data):
    5. BiTreeNode.__init__(self,data)
    6. #self.bf=0 #此处的self.bf添加到BiTreeNode.__inint__中去
    7. class AVLTree(BST):
    8. def __init__(self,li=None):
    9. BST.__init__(self,li)
    10. def rotate_left(self,p,c): #此函数只用于插入时,没问题,用于删除时,有问题
    11. s2=c.lchild
    12. p.rchild=s2
    13. if s2:
    14. s2.parent=p
    15. c.lchild=p
    16. p.parent=c
    17. p.bf=0
    18. c.bf=0
    19. return c
    20. def rotate_right(self,p,c):
    21. s2=c.rchild
    22. p.lchild=s2
    23. if s2:
    24. s2.parent=p
    25. c.rchild=p
    26. p.parent=c
    27. p.bf=0
    28. c.bf=0
    29. return c
    30. def rotate_right_left(self,p,c):
    31. g=c.lchild
    32. s3=g.rchild
    33. c.lchild=s3
    34. if s3:
    35. s3.parent=c
    36. g.rchild=c
    37. c.parent=g
    38. s2=g.lchild
    39. p.rchild=s2
    40. if s2:
    41. s2.parent=p
    42. g.lchild=p
    43. p.parent=g
    44. #更新bf
    45. if g.bf>0:
    46. p.bf=-1
    47. c.bf=0
    48. elif g.bf<0:
    49. p.bf=0
    50. c.bf=1
    51. else: #插入的是g
    52. p.bf=0
    53. c.bf=0
    54. return g #返回根节点
    55. def rotate_left_right(self,p,c):
    56. g=c.rchild
    57. s2=g.lchild
    58. c.rchild=s2
    59. if s2:
    60. s2.parent=c
    61. g.lchild=c
    62. c.parent=g
    63. s3=g.rchild
    64. p.lchild=s3
    65. if s3:
    66. s3.parent=p
    67. g.rchild=p
    68. p.parent=g
    69. #更新bf
    70. if g.bf<0:
    71. c.bf=0
    72. p.bf=1
    73. elif g.bf>0:
    74. p.bf=0
    75. c.bf=-1
    76. else: #插入的是g
    77. p.bf=0
    78. c.bf=0
    79. return g
    80. def insert_no_rec(self,val):
    81. # 1、和二叉搜索(bst)数一样,插入
    82. p=self.root
    83. if not p: #空树时,直接定义个二叉树根节点
    84. self.root=BiTreeNode(val)
    85. return
    86. while True:
    87. if val<p.data:
    88. if p.lchild: #此处可看出与递归的方式的区别
    89. p=p.lchild
    90. else: #左孩子不存在
    91. p.lchild=BiTreeNode(val)
    92. p.lchild.parent=p
    93. node=p.lchild #node存储的是插入的节点
    94. break
    95. elif val>p.data:
    96. if p.rchild:
    97. p=p.rchild
    98. else:
    99. p.rchild=BiTreeNode(val)
    100. p.rchild.parent=p
    101. node=p.rchild
    102. break
    103. else: # val=p.data
    104. return
    105. #2、更新bf
    106. while node.parent: #node.parent不空
    107. if node.parent.lchild==node:#传递是从左子树来的,左子树更沉了
    108. #更新node.parent的bf -=1
    109. if node.parent.bf <0: #原来node.parent.bf=-1,更新之后变成-2
    110. #做旋转
    111. #看node哪边沉
    112. x=node.parent #旋转前的子树的根
    113. g=node.parent.parent #为了连接旋转之后的子树
    114. if node.bf>0:
    115. n=self.rotate_left_right(node.parent,node)
    116. else:
    117. n=self.rotate_right(node.parent,node)
    118. # 记得把n和g连起来
    119. elif node.parent.bf>0: #原来node.parent.bf=1,更新之后变成0
    120. node.parent.bf=0
    121. break
    122. else: #原来node.parent.bf=0,更新之后变成-1
    123. node.parent.bf=-1
    124. node=node.parent
    125. continue
    126. else:#传递是从右子树来的,右子树更沉了
    127. #更新node.parent.bf+=1
    128. if node.parent.bf>0: #原来node.parent.bf=1,更新之后变成2
    129. #做旋转
    130. #看node哪边沉
    131. g=node.parent.parent
    132. x=node.parent #旋转前的子树的根
    133. if node.bf<0: #node.bf= -1
    134. n=self.rotate_right_left(node.parent,node)
    135. else: #node.bf= 1
    136. n=self.rotate_left(node.parent,node)
    137. # 记得连起来
    138. elif node.parent.bf<0: #原来node.parent.bf=-1,更新之后变成0
    139. node.parent.bf=0
    140. break
    141. else: #原来node.parent.bf=0,更新之后变成1
    142. node.parent.bf=1
    143. node=node.parent
    144. continue
    145. #连接旋转后的子树
    146. n.parent=g
    147. if g: #g不是空
    148. if x==g.lchild:
    149. g.lchild=n
    150. else:
    151. g.rchild=n
    152. break
    153. else:
    154. self.root=n
    155. break
    156. tree=AVLTree([9,8,7,6,5,4,3,2,1])
    157. tree.pre_order(tree.root)
    158. print("")
    159. tree.in_order(tree.root)