python实现二叉树的遍历

绝地灬酷狼 2022-11-13 09:26 251阅读 0赞

遍历二叉树就是以一定的规则将二叉树中的结点排列成一个线性序列,从而得到二叉树节点的各种遍历序列。其实质就是对一个非线性结构进行线性操作,使在这个序列中,除了第一个和最后一个结点,每个结点都有一个直接前驱和直接后继。
先序遍历
如果二叉树为空,则什么也不做;
否则:
1.访问根节点
2.先序遍历左子树
3.先序遍历右子树

中序遍历
如果二叉树为空,则什么也不做;
否则:
1.中序遍历左子树
2.访问根节点
3.中序遍历右子树
后序遍历
如果二叉树为空,则什么也不做;
否则:
1.后序遍历左子树
2.后序遍历右子树
3.访问根节点

层次遍历
要进行层次遍历需要借助一个队列。先将二叉树根结点入队,然后出队,访问该结点,如果它有左子树,则将左子树根结点入队;如果它有右子树,则将右子树根结点入队。然后出队,对出队结点访问,如此反复,直到队列为空。
在这里插入图片描述
代码如下:

  1. # 二叉树类
  2. class BTree(object):
  3. # 初始化
  4. def __init__(self, data=None, left=None, right=None):
  5. self.data = data # 数据域
  6. self.left = left # 左子树
  7. self.right = right # 右子树
  8. # 前序遍历:中->左->右
  9. def preorder(self):
  10. if self.data:
  11. print(self.data, end=' ')
  12. if self.left:
  13. self.left.preorder()
  14. if self.right:
  15. self.right.preorder()
  16. # 中序遍历:左->中->右
  17. def inorder(self):
  18. if self.left :
  19. self.left.inorder()
  20. if self.data :
  21. print(self.data, end=' ')
  22. if self.right :
  23. self.right.inorder()
  24. # 后序遍历:左->右->中
  25. def postorder(self):
  26. if self.left :
  27. self.left.postorder()
  28. if self.right :
  29. self.right.postorder()
  30. if self.data :
  31. print(self.data, end=' ')
  32. # 层序遍历:
  33. def levelorder(self):
  34. # 返回某个节点的左孩子
  35. def LChild_Of_Node(node):
  36. return node.left if node.left else None
  37. # 返回某个节点的右孩子
  38. def RChild_Of_Node(node):
  39. return node.right if node.right else None
  40. # 层序遍历列表
  41. level_order = []
  42. # 传入的self为根结点,添加根节点中的数据到level_order,即:二叉树的根节点入队
  43. if self.data :
  44. print("self:",self.data)
  45. level_order.append([self])
  46. # 二叉树的高度
  47. height = self.height()
  48. if height >= 1:
  49. # 对第二层及其以后的层数进行操作, 在level_order中添加节点而不是数据
  50. for _ in range(2, height + 1):
  51. level = [] # 该层的节点
  52. for node in level_order[-1]:
  53. # 如果它有左子树,则将左子树节点入队
  54. if LChild_Of_Node(node):
  55. level.append(LChild_Of_Node(node))
  56. # 如果它有右子树,则将右子树结点入队
  57. if RChild_Of_Node(node):
  58. level.append(RChild_Of_Node(node))
  59. if level: # 如果该层非空,则添加该层
  60. level_order.append(level)
  61. # 取出每层中的数据
  62. for i in range(0, height): # 层数
  63. for index in range(len(level_order[i])):
  64. level_order[i][index] = level_order[i][index].data
  65. return level_order
  66. # 二叉树的高度
  67. def height(self):
  68. # 空的树高度为0, 只有root节点的树高度为1
  69. if self.data is None:
  70. return 0
  71. #左右子树都为空,则当前结点为叶子结点
  72. elif self.left is None and self.right is None:
  73. return 1
  74. elif self.left is None and self.right :
  75. return 1 + self.right.height()
  76. elif self.left and self.right is None:
  77. return 1 + self.left.height()
  78. else:
  79. return 1 + max(self.left.height(), self.right.height())
  80. # 二叉树的叶子节点
  81. def leaves(self):
  82. if self.data is None:
  83. return None
  84. elif self.left is None and self.right is None:
  85. print(self.data, end=' ')
  86. elif self.left is None and self.right :
  87. self.right.leaves()
  88. elif self.right is None and self.left :
  89. self.left.leaves()
  90. else:
  91. self.left.leaves()
  92. self.right.leaves()
  93. if __name__ == '__main__':
  94. right_tree = BTree(6)
  95. right_tree.left = BTree(2)
  96. right_tree.right = BTree(4)
  97. left_tree = BTree(5)
  98. left_tree.left = BTree(1)
  99. left_tree.right = BTree(3)
  100. tree = BTree(11)
  101. tree.left = left_tree
  102. tree.right = right_tree
  103. left_tree = BTree(7)
  104. left_tree.left = BTree(3)
  105. left_tree.right = BTree(4)
  106. right_tree = tree # 增加新的变量
  107. tree = BTree(18)
  108. tree.left = left_tree
  109. tree.right = right_tree
  110. print('先序遍历为:')
  111. tree.preorder()
  112. print()
  113. print('中序遍历为:')
  114. tree.inorder()
  115. print()
  116. print('后序遍历为:')
  117. tree.postorder()
  118. print()
  119. print('层序遍历为:')
  120. level_order = tree.levelorder()
  121. print(level_order)
  122. print()
  123. height = tree.height()
  124. print('树的高度为%s.' % height)
  125. print('叶子节点为:')
  126. tree.leaves()
  127. print()
  128. # 先序遍历为:
  129. # 18 7 3 4 11 5 1 3 6 2 4
  130. # 中序遍历为:
  131. # 3 7 4 18 1 5 3 11 2 6 4
  132. # 后序遍历为:
  133. # 3 4 7 1 3 5 2 4 6 11 18
  134. # 层序遍历为:
  135. # self: 18
  136. # [[18], [7, 11], [3, 4, 5, 6], [1, 3, 2, 4]]
  137. #
  138. # 树的高度为4.
  139. # 叶子节点为:
  140. # 3 4 1 3 2 4

也可以换一种方式构造二叉树,利用层序遍历的原理逐层创建,代码如下:

  1. # 二叉树类
  2. class BTree(object):
  3. # 初始化
  4. def __init__(self, data=None, left=None, right=None):
  5. self.data = data # 数据域
  6. self.left = left # 左子树
  7. self.right = right # 右子树
  8. # 前序遍历:中->左->右
  9. def preorder(self):
  10. if self.data:
  11. print(self.data, end=' ')
  12. if self.left:
  13. self.left.preorder()
  14. if self.right:
  15. self.right.preorder()
  16. # 中序遍历:左->中->右
  17. def inorder(self):
  18. if self.left :
  19. self.left.inorder()
  20. if self.data :
  21. print(self.data, end=' ')
  22. if self.right :
  23. self.right.inorder()
  24. # 后序遍历:左->右->中
  25. def postorder(self):
  26. if self.left :
  27. self.left.postorder()
  28. if self.right :
  29. self.right.postorder()
  30. if self.data :
  31. print(self.data, end=' ')
  32. # 层序遍历:
  33. def levelorder(self):
  34. # 返回某个节点的左孩子
  35. def LChild_Of_Node(node):
  36. return node.left if node.left else None
  37. # 返回某个节点的右孩子
  38. def RChild_Of_Node(node):
  39. return node.right if node.right else None
  40. # 层序遍历列表
  41. level_order = []
  42. # 传入的self为根结点,添加根节点中的数据到level_order,即:二叉树的根节点入队
  43. if self.data :
  44. print("self:",self.data)
  45. level_order.append([self])
  46. # 二叉树的高度
  47. height = self.height()
  48. if height >= 1:
  49. # 对第二层及其以后的层数进行操作, 在level_order中添加节点而不是数据
  50. for _ in range(2, height + 1):
  51. level = [] # 该层的节点
  52. for node in level_order[-1]:
  53. # 如果它有左子树,则将左子树节点入队
  54. if LChild_Of_Node(node):
  55. level.append(LChild_Of_Node(node))
  56. # 如果它有右子树,则将右子树结点入队
  57. if RChild_Of_Node(node):
  58. level.append(RChild_Of_Node(node))
  59. if level: # 如果该层非空,则添加该层
  60. level_order.append(level)
  61. # 取出每层中的数据
  62. for i in range(0, height): # 层数
  63. for index in range(len(level_order[i])):
  64. level_order[i][index] = level_order[i][index].data
  65. return level_order
  66. # 二叉树的高度
  67. def height(self):
  68. # 空的树高度为0, 只有root节点的树高度为1
  69. if self.data is None:
  70. return 0
  71. #左右子树都为空,则当前结点为叶子结点
  72. elif self.left is None and self.right is None:
  73. return 1
  74. elif self.left is None and self.right :
  75. return 1 + self.right.height()
  76. elif self.left and self.right is None:
  77. return 1 + self.left.height()
  78. else:
  79. return 1 + max(self.left.height(), self.right.height())
  80. # 二叉树的叶子节点
  81. def leaves(self):
  82. if self.data is None:
  83. return None
  84. elif self.left is None and self.right is None:
  85. print(self.data, end=' ')
  86. elif self.left is None and self.right :
  87. self.right.leaves()
  88. elif self.right is None and self.left :
  89. self.left.leaves()
  90. else:
  91. self.left.leaves()
  92. self.right.leaves()
  93. # 利用列表构造二叉树
  94. # 列表中至少有一个元素
  95. def create_BTree_By_List(array):
  96. i = 1
  97. # 将原数组拆成层次遍历的数组,每一项都储存这一层所有的节点的数据
  98. level_order = []
  99. sum = 1
  100. #二叉树每层元素数目为pow(2,n-1),索引为i-1:i*2-1
  101. while sum < len(array):
  102. level_order.append(array[i-1:2*i-1])
  103. i *= 2
  104. sum += i
  105. level_order.append(array[i-1:])#如果不是满二叉树,则剩余的放到最后一层
  106. # BTree_list: 这一层所有的节点组成的列表
  107. # forword_level: 上一层节点的数据组成的列表
  108. def Create_BTree_One_Step_Up(BTree_list, forword_level):
  109. new_BTree_list = []#最终得到一层有左右子树的结点
  110. i = 0
  111. for elem in forword_level:#这是父节点的集合,给结点分配左右子树
  112. root = BTree(elem)
  113. if 2*i < len(BTree_list):#左子树
  114. root.left = BTree_list[2*i]
  115. if 2*i+1 < len(BTree_list):#右子树
  116. root.right = BTree_list[2*i+1]
  117. new_BTree_list.append(root)
  118. i += 1
  119. return new_BTree_list
  120. # 只有一层:即只有一个节点
  121. if len(level_order) == 1:
  122. return BTree(level_order[0][0])
  123. else: # 二叉树的层数大于1
  124. # 创建最后一层的节点列表
  125. BTree_list = [BTree(elem) for elem in level_order[-1]]
  126. # 从下往上,逐层创建二叉树:BTree_list是每一层的节点集合
  127. for i in range(len(level_order)-2, -1, -1):
  128. BTree_list = Create_BTree_One_Step_Up(BTree_list, level_order[i])
  129. return BTree_list[0]
  130. if __name__ == '__main__':
  131. array = [chr(x) for x in range(65,91)]
  132. tree = create_BTree_By_List(array)
  133. print('先序遍历为:')
  134. tree.preorder()
  135. height = tree.height()
  136. print('树的高度为%s.'%height)
  137. print('层序遍历为:')
  138. level_order = tree.levelorder()
  139. print(level_order)
  140. print('叶子节点为:')
  141. tree.leaves()
  142. # 先序遍历为:
  143. # A B D H P Q I R S E J T U K V W C F L X Y M Z G N O 树的高度为5.
  144. # 层序遍历为:
  145. # self: A
  146. # [['A'], ['B', 'C'], ['D', 'E', 'F', 'G'], ['H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'], ['P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']]
  147. # 叶子节点为:
  148. # P Q R S T U V W X Y Z N O

发表评论

表情:
评论列表 (有 0 条评论,251人围观)

还没有评论,来说两句吧...

相关阅读

    相关 python实现

    遍历二叉树就是以一定的规则将二叉树中的结点排列成一个线性序列,从而得到二叉树节点的各种遍历序列。其实质就是对一个非线性结构进行线性操作,使在这个序列中,除了第一个和最后一个结点

    相关 c++实现

    //自己还真是个菜鸡,大一学了一年c++,现在还在基础的语法上转圈,还没有意识到c++真正的 //的强大之处在于它的多变,封装,等算法告一段落了在考虑是往Jav

    相关 python

    从二叉树的根节点出发,节点的遍历分为三个主要步骤:对当前节点进行操作(称为“访问”节点,或者根节点)、遍历左边子节点、遍历右边子节点。访问节点顺序的不同也就形成了不同的遍历方式