二叉树的深度优先遍历(DFS)和广度优先遍历(BFS)
从leetcode的一道题目说起
二叉树的层次遍历
题目链接添加链接描述
给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
例如:
给定二叉树: [3,9,20,null,null,15,7],
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
这个题目明显就是广度遍历二叉树,并将树的每一层分别输出。
class Solution:
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
res = []
tmp = [[root]]
if root == None:
return res
while tmp != []:
s = tmp.pop(0)
tmp1 = []
tmp2 = []
for i in range(len(s)):
tmp1.append(s[i].val)
if s[i].left !=None:
tmp2.append(s[i].left)
if s[i].right != None:
tmp2.append(s[i].right)
if tmp2 != []:
tmp.append(tmp2)
res.append(tmp1)
return res
关于二叉树的深度优先遍历和广度广度遍历:
1、深度优先遍历常用的数据结构为栈,广度优先遍历常用的数据结构为队列
2、深度优先遍历的思想是从上至下,对每一个分支一直往下一层遍历直到这个分支结束,然后返回上一层,对上一层的右子树这个分支继续深搜,直到一整棵树完全遍历,因此深搜的步骤符合栈后进先出的特点
广度优先遍历的思想是从左至右,对树的每一层所有结点依次遍历,当一层的结点遍历完全后,对下一层开始遍历,而下一层结点又恰好是上一层的子结点。因此广搜的步骤符合队列先进先出的思想。
3、关于二叉树的深度优先搜索
则又有三种遍历方法
先序遍历:对任一子树,先访问根,然后遍历其左子树,最后遍历其右子树。
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树。
后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
除了利用栈以外,深度优先搜索也可以使用递归的方法。’
4、深度优先搜索算法:不全部保留结点,占用空间少;有回溯操作(即有入栈、出栈操作),运行速度慢。
广度优先搜索算法:保留全部结点,占用空间大; 无回溯操作(即无入栈、出栈操作),运行速度快。
队列广搜
如上面leetdode题目
递归深搜
list1=[] #前序遍历输
list2=[] #中序遍历
list3=[] #后序遍历
def qianxubianli(t):
if t:
list1.append(t.root)
qianxubianli(t.getleftchild())
qianxubianli(t.getrightchild())
return list1
def zhongxubianli(t):
if t:
zhongxubianli(t.getleftchild())
list2.append(t.root)
zhongxubianli(t.rightchild)
return list2
def houxubianli(t):
if t:
houxubianli(t.getleftchild())
houxubianli(t.getrightchild())
list3.append(t.root)
return list3
栈深搜
72 # 队栈实现先序遍历
73 def front_queueAndStack(self,root):
74 if root==None:
75 return
76 #定义一个栈,存储节点
77 stack=[]
78 node=root
79 while stack or node:
80 #从树根开始一直输出左孩子
81 while node:
82 print node.data,
83 #将输出的节点加入栈中
84 stack.append(node)
85 node=node.lchild
86 #该节点不存在左节点时,该节点出栈,搜索该节点右节点,
87 node=stack.pop()
88 node=node.rchild
89 # 队栈实现中序遍历
90 def middle_queueAndStack(self,root):
91 if root==None:
92 return
93 # 定义一个栈,存储节点
94 stack = []
95 node = root
96 while stack or node:
97 #一直查找树的左节点,一直进栈
98 while node:
99 stack.append(node)
100 node=node.lchild
101 node=stack.pop()#该节点不存在左节点,该节点出栈,查找右节点
102 print node.data,
103 node=node.rchild
104 # 队栈实现后序遍历
105 def behind_queueAndStack(self,root):
106 if root==None:
107 return
108 # 定义一个栈,存储节点
109 stack_1 = []
110 stack_2 = []
111 node = root
112 stack_1.append(node)
113 while stack_1:
114 #该节点出栈1.左右节点进栈1(对于左右节点,右节点先出栈1,也先进栈1)
115 node=stack_1.pop()
116 if node.lchild:
117 stack_1.append(node.lchild)
118 if node.rchild:
119 stack_1.append(node.rchild)
120 #该节点进栈2
121 stack_2.append(node)
122 while stack_2:
123 print stack_2.pop().data