二叉树的深度优先遍历和广度优先遍历
程序员文章站
2022-05-21 19:27:41
...
二叉树的深度优先遍历(DFS)和广度优先遍历(BFS)
-
深度优先
深度优先遍历的思想是从上至下,对每一个分支一直往下一层遍历直到这个分支结束,然后返回上一层,对上一层的右子树这个分支继续深搜,直到一整棵树完全遍历,因此深搜的步骤符合栈先进后出的特点。
深度优先有三种遍历方式:先序(根,左,右),后序(左,右,根),中序(根,左,右)。
本文中实现了三种遍历方式的递归和非递归遍方式。 -
广度优先
广度优先遍历的思想是从左至右,对树的每一层所有结点依次遍历,当一层的结点遍历完全后,对下一层开始遍历,而下一层结点又恰好是上一层的子结点。因此广搜的步骤符合队列先进先出的思想。
广度优先遍历用来求二叉树的深度,最大宽度比较方便。
参考文章中关于树的问题讲解的不错
#!/usr/bin/env python3
class binaryTreeNone(object):
def __init__(self,x):
self.val = x
self.left =None
self.right = None
##递归实现
def pre(self,root): ##先序遍历
if root == None:
return
print(root.val, end=" ")
self.pre(root.left)
self.pre(root.right)
#return pre_list
def middle(self,root):
if root == None:
return
self.middle(root.left)
print(root.val, end=" ")
self.middle(root.right)
def last(self,root):
if root == None:
return
self.last(root.left)
self.last(root.right)
print(root.val, end=" ")
#非递归实现 用栈实现
def pre_1(self,root):
tempNode = root
Stack=[]
while tempNode or Stack: #当栈和root都为空的时候,表示访问结束
while tempNode: #循环结束时,代表左子树已访问完,从栈中取出根节点,访问右子树
print(tempNode.val,end=' ')
Stack.append(tempNode)
tempNode= tempNode.left
Node = Stack.pop()
tempNode = Node.right
def middle_1(self,root):
tempNode = root
Stack =[]
while tempNode or Stack:
while tempNode:
Stack.append(tempNode)
tempNode = tempNode.left
node = Stack.pop()
print(node.val,end =" ")
tempNode = node.right
def last_1(selfself,root):
tempNode = root
Stack=[]
while tempNode or Stack:
while tempNode:
Stack.append(tempNode)
tempNode = tempNode.left
node = Stack[-1] #判断栈顶元素与其右子树的关系
tempNode= node.right
if node.right == None:
print(node.val,end =' ') ##右子树为空,访问节点
node = Stack.pop() #访问完了,从栈中弹出
while Stack and node == Stack[-1].right: #栈顶右子树已经访问过 ,即可访问栈顶元素
node= Stack.pop()
print(node.val,end =" ")
def last_2(self,root): #需要额外的空间
tempNode = root
Stack =[]
out_put =[]
while tempNode or Stack: #左右根, 根右左
while tempNode :
out_put.append(tempNode.val)
Stack.append(tempNode)
tempNode = tempNode.right
node = Stack.pop()
tempNode = node.left
out_put.reverse()
print(out_put)
#二叉树的广度优先遍历 ,用队列实现
def bfs(self,root):
tempNode = root
que=[]
que.append(tempNode)
while que:
tempNode = que.pop(0)
print(tempNode.val, end = ' ')
if tempNode.left:
que.append(tempNode.left) #将孩子加入队列
if tempNode.right:
que.append(tempNode.right)
#计算数的深度 递归
def countDepth_1(self,root):
depth =0
if root == None:
return depth
if root:
# depth+=1
depth =max(self.countDepth_1(root.left),self.countDepth_1(root.right))+1
return depth
def countDepth_2(self,root):
que =[]
depth =0
max_with =0 #最大宽度
if root ==None:
return depth
que.append(root) #将根入队列
while que:
n = len(que) ##目前层次的结点数
if max_with <n:
max_with =n
depth+=1
while n>0: #将目前层次结点的孩子(即下一层的结点)入队列
node = que.pop(0)
n -= 1
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
return depth,max_with
if __name__ == '__main__':
node1 = binaryTreeNone(1)
node2 = binaryTreeNone(2)
node3 = binaryTreeNone(3)
node4= binaryTreeNone(4)
node5 = binaryTreeNone(5)
node6 = binaryTreeNone(6)
node7 = binaryTreeNone(7)
node1.left = node2
node1.right = node3
node2.left = node4
node2.right = node5
node3.left = node6
node3.right = node7
print("先序遍历递归实现: ",end=" ")
node1.pre(node1)
print("\n先序遍历非递归实现:", end=" ")
node1.pre_1(node1)
print("\n中序遍历递归实现:", end=" ")
node1.middle(node1)
print("\n中序遍历非递归实现:", end=" ")
node1.middle_1(node1)
print("\n后序遍历递归实现: ", end=" ")
node1.last(node1)
print("\n后序遍历非递归实现1:", end=" ")
node1.last_1(node1)
print("\n后序遍历非递归实现2:", end=" ")
node1.last_2(node1)
print(" ")
print("************************")
print("广度优先遍历:")
node1.bfs(node1)
print(" ")
print("*"*50)
print("树的深度递归实现:",node1.countDepth_1(node1))
print("树的深度非递归实现:", node1.countDepth_2(node1))
上一篇: 树的深度和广度优先遍历
下一篇: 类加载机制笔记——类初始化时机