在上一节二叉树的基础上我们实现,如何将生成平衡的二叉树

  所谓平衡二叉树:

    我自己定义就是:任何一个节点的左高度和右高度的差的绝对值都小于2

    如图所示此时a的左高度等于3,有高度等于1,差值为2,属于不平衡中的左偏

  

  此时的处理办法就是:

    将不平衡的元素的左枝的最右节点变为当前节点,

    此时分两种情况:

     一、左枝有最右节点

      将最右节点的左枝赋予其父节点的右枝

     二、左枝没有最右节点,

      直接将左枝节点做父级节点,父级节点做其右枝

      

 

  如图所示,图更清楚些。

    假定a左偏,就需要一个比a小的最少一个值d(因为d唯一 一个是比a小,而且比a的左枝所有数都大的值)做父集结点,a做d的右枝,这样在最上面的d节点就平衡了。

    我们可以反证一下:

     如果不是d是另一个数假设为h,此时h做父节点,a做父节点的右节点

      因为a在h右边,所以 a > h

      因为b,e,d,f都是h的左枝,所以  h>d>b>e>f

      所以 a>h>d>b>e>f

      所以在不加入新节点的情况下,就只能是d    

 

左偏和右偏是一样的,可以完全镜像过来就ok了

处理了所有节点 的左偏和右偏使整个二叉树平衡,这就是平衡二叉树的基本思想

  1. # -*- coding:utf-8 -*-
  2. # 日期:2018/6/12 8:37
  3. # Author:小鼠标
  4.  
  5. # 节点对象
  6. class Node:
  7. def __init__(self):
  8. self.left_children = None
  9. self.left_height = 0
  10. self.right_children = None
  11. self.right_height = 0
  12. self.value = None
  13. # 二叉树对象
  14. class tree:
  15. def __init__(self):
  16. self.root = False
  17. self.front_list = []
  18. self.middle_list = []
  19. self.after_list = []
  20. # 生成二叉树
  21. def create_tree(self,n=0,l=[]):
  22. if l == []:
  23. print("传入的列表为空")
  24. return
  25. if n > len(l)-1:
  26. print("二叉树生成")
  27. return
  28. node = Node()
  29. node.value = l[n]
  30. if not self.root:
  31. self.root = node
  32. self.list = l
  33. else:
  34. self.add(self.root,node)
  35. self.create_tree(n+1,l)
  36. # 添加节点
  37. def add(self,parent,new_node):
  38. if new_node.value > parent.value:
  39. # 插入值比父亲值大,所以在父节点右边
  40. if parent.right_children == None:
  41. parent.right_children = new_node
  42. # 新插入节点的父亲节点的高度值为1,也就是子高度值0+1
  43. parent.right_height = 1
  44. # 插入值后 从下到上更新节点的height
  45. else:
  46. self.add(parent.right_children,new_node)
  47. # 父亲节点的右高度等于右孩子,左右高度中较大的值 + 1
  48. parent.right_height = max(parent.right_children.right_height, parent.right_children.left_height) + 1
  49. # ======= 此处开始判断平衡二叉树=======
  50. # 右边高度大于左边高度 属于右偏
  51. if parent.right_height - parent.left_height >= 2:
  52. self.right_avertence(parent)
  53. else:
  54. # 插入值比父亲值小,所以在父节点左边
  55. if parent.left_children == None:
  56. parent.left_children = new_node
  57. parent.left_height = 1
  58. else:
  59. self.add(parent.left_children,new_node)
  60. parent.left_height = max(parent.left_children.right_height, parent.left_children.left_height) + 1
  61. # ======= 此处开始判断平衡二叉树=======
  62. # 左边高度大于右边高度 属于左偏
  63. if parent.left_height - parent.right_height >= 2:
  64. self.left_avertence(parent)
  65. # 更新当前节点下的所有节点的高度
  66. def update_height(self,node):
  67. # 初始化节点高度值为0
  68. node.left_height = 0
  69. node.right_height = 0
  70. # 是否到最底层的一个
  71. if node.left_children == None and node.right_children == None:
  72. return
  73. else:
  74. if node.left_children:
  75. self.update_height(node.left_children)
  76. # 当前节点的高度等于左右子节点高度的较大值 + 1
  77. node.left_height = max(node.left_children.left_height,node.left_children.right_height) + 1
  78. if node.right_children:
  79. self.update_height(node.right_children)
  80. # 当前节点的高度等于左右子节点高度的较大值 + 1
  81. node.right_height = max(node.right_children.left_height, node.right_children.right_height) + 1
  82. # 检查是否仍有不平衡
  83. if node.left_height - node.right_height >= 2:
  84. self.left_avertence(node)
  85. elif node.left_height - node.right_height <= -2:
  86. self.right_avertence(node)
  87. def right_avertence(self,node):
  88. # 右偏 就将当前节点的最左节点做父亲
  89. new_code = Node()
  90. new_code.value = node.value
  91. new_code.left_children = node.left_children
  92. best_left = self.best_left_right(node.right_children)
  93. v = node.value
  94. # 返回的对象本身,
  95. if best_left == node.right_children and best_left.left_children == None:
  96. # 说明当前节点没有有节点
  97. node.value = best_left.value
  98. node.right_children = best_left.right_children
  99. else:
  100. node.value = best_left.left_children.value
  101. best_left.left_children = best_left.left_children.right_children
  102. node.left_children = new_code
  103. self.update_height(node)
  104. # 处理左偏情况
  105. def left_avertence(self,node):
  106. new_code = Node()
  107. new_code.value = node.value
  108. new_code.right_children = node.right_children
  109. best_right = self.best_left_right(node.left_children,1)
  110. v = node.value
  111. # 返回的对象本身,
  112. if best_right == node.left_children and best_right.right_children == None:
  113. # 说明当前节点没有有节点
  114. node.value = best_right.value
  115. node.left_children = best_right.left_children
  116. else:
  117. node.value = best_right.right_children.value
  118. best_right.right_children = best_right.right_children.left_children
  119. node.right_children = new_code
  120. self.update_height(node)
  121. # 返回node节点最左(右)子孙的父级
  122. def best_left_right(self,node,type=0):
  123. # type=0 默认找最左子孙
  124. if type == 0:
  125. if node.left_children == None:
  126. return node
  127. elif node.left_children.left_children == None:
  128. return node
  129. else:
  130. return self.best_left_right(node.left_children,type)
  131. else:
  132. if node.right_children == None:
  133. return node
  134. elif node.right_children.right_children == None:
  135. return node
  136. else:
  137. return self.best_left_right(node.right_children,type)
  138. # 前序(先中再左最后右)
  139. def front(self,node=None):
  140. if node == None:
  141. self.front_list = []
  142. node = self.root
  143. # 输出当前节点
  144. self.front_list.append(node.value)
  145. # 先判断左枝
  146. if not node.left_children == None:
  147. self.front(node.left_children)
  148. # 再判断右枝
  149. if not node.right_children == None:
  150. self.front(node.right_children)
  151. # 返回最终结果
  152. return self.front_list
  153. # 中序(先左再中最后右)
  154. def middle(self,node=None):
  155. if node == None:
  156. node = self.root
  157. # 先判断左枝
  158. if not node.left_children == None:
  159. self.middle(node.left_children)
  160. # 输出当前节点
  161. self.middle_list.append(node.value)
  162. # 再判断右枝
  163. if not node.right_children == None:
  164. self.middle(node.right_children)
  165. return self.middle_list
  166. # 后序(先左再右最后中)
  167. def after(self,node=None):
  168. if node == None:
  169. node = self.root
  170. # 先判断左枝
  171. if not node.left_children == None:
  172. self.after(node.left_children)
  173. # 再判断右枝
  174. if not node.right_children == None:
  175. self.after(node.right_children)
  176. self.after_list.append(node.value)
  177. return self.after_list
  178. # 节点删除
  179. def del_node(self,v,node=None):
  180. if node == None:
  181. node = self.root
  182. # 删除根节点
  183. if node.value == v:
  184. self.del_root(self.root)
  185. return
  186. # 删除当前节点的左节点
  187. if node.left_children:
  188. if node.left_children.value == v:
  189. self.del_left(node)
  190. return
  191. # 删除当前节点的右节点
  192. if node.right_children:
  193. if node.right_children.value == v:
  194. self.del_right(node)
  195. return
  196. if v > node.value:
  197. if node.right_children:
  198. self.del_node(v, node.right_children)
  199. else:
  200. print("删除的元素不存在")
  201. else:
  202. if node.left_children:
  203. self.del_node(v, node.left_children)
  204. else:
  205. print("删除的元素不存在")
  206. #删除当前节点的右节点
  207. def del_right(self,node):
  208. # 情况1 删除节点没有右枝
  209. if node.right_children.right_children == None:
  210. node.right_children = node.right_children.left_children
  211. else:
  212. best_left = self.best_left_right(node.right_children.right_children)
  213. # 表示右枝最左孙就是右枝本身
  214. if best_left == node.right_children.right_children and best_left.left_children == None:
  215. node.right_children.value = best_left.value
  216. node.right_children.right_children = best_left.right_children
  217. else:
  218. node.right_children.value = best_left.left_children.value
  219. best_left.left_children = best_left.left_children.right_children
  220. # 删除当前节点的左节点
  221. def del_left(self,node):
  222. # 情况1 删除节点没有右枝
  223. if node.left_children.right_children == None:
  224. node.left_children = node.left_children.left_children
  225. else:
  226. best_left = self.best_left_right(node.left_children.right_children)
  227. # 表示右枝最左子孙就是右枝本身
  228. if best_left == node.left_children.right_children and best_left.left_children == None:
  229. node.left_children.value = best_left.value
  230. node.left_children.right_children = best_left.right_children
  231. else:
  232. node.left_children.value = best_left.left_children.value
  233. best_left.left_children = best_left.left_children.right_children
  234. # 删除根节点
  235. def del_root(self,node):
  236. if node.right_children == None:
  237. if node.left_children == None:
  238. node.value = None
  239. else:
  240. self.root = node.left_children
  241. else:
  242. best_left = self.best_left_right(node.right_children)
  243. # 表示右枝最左子孙就是右枝本身
  244. if best_left == node.right_children and best_left.left_children == None:
  245. node.value = best_left.value
  246. node.right_children = best_left.right_children
  247. else:
  248. node.value = best_left.left_children.value
  249. best_left.left_children = best_left.left_children.right_children
  250. # 搜索
  251. def search(self,v,node=None):
  252. if node == None:
  253. node = self.root
  254. if node.value == v:
  255. return True
  256. if v > node.value:
  257. if not node.right_children == None:
  258. return self.search(v, node.right_children)
  259. else:
  260. if not node.left_children == None:
  261. return self.search(v, node.left_children)
  262. return False
  263. if __name__ == \'__main__\':
  264. # 需要建立二叉树的列表
  265. list = [4, 6, 3, 1, 7, 9, 8, 5, 2]
  266. t = tree()
  267. t.create_tree(0,list)
  268. res = t.front()
  269. print(\'前序\', res)

执行结果:

  前序 [4, 2, 1, 3, 7, 6, 5, 9, 8]

  通过前序可以画出二叉树

完美,哈哈。

这是我钻了两天才写出的代码,哈哈,努力还是有回报的,加油。

 下一步就是代码优化了

版权声明:本文为7749ha原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/7749ha/p/9179086.html