二叉树的深度优先遍历(DFS)和广度优先遍历(BFS)

二叉树的深度优先遍历(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
  • 13
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值