【Leetcode】二叉树的遍历2

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用



前言

【Leetcode】#144. 二叉树的前序遍历
【Leetcode】#94. 二叉树的中序遍历
【Leetcode】#145. 二叉树的后序遍历

有两种通用的遍历树的策略:

  • 深度优先搜索DFS

    在这个策略中,我们采用深度作为优先级,以便从根开始一直到达某个确定的叶子,然后再返回根到达另一个分支。

    深度优先搜索策略又可以根据根节点、左孩子和右孩子的相对顺序被细分为前序遍历中序遍历后序遍历

  • 宽度优先搜索BFS

    我们按照高度顺序一层一层的访问整棵树,高层次的节点将会比低层次的节点先被访问到。

下图中的顶点按照访问的顺序编号,按照 1-2-3-4-5 的顺序来比较不同的策略。

在这里插入图片描述

使用递归方法很简单,可以通过迭代算法来解


深度遍历-方法1:递归

# 前序
def preorderTraversal(self, root):
    if root is None: return []
    out = [root.val]
    out.extend(self.preorderTraversal(root.left))
    out.extend(self.preorderTraversal(root.right))
    return out


# 中序
def inorderTraversal(self, root):
    if root is None: return []    
    out.extend(self.inorderTraversal(root.left))
    out = [root.val]
    out.extend(self.inorderTraversal(root.right))
    return out


# 后序
def postorderTraversal(self, root):
    if root is None: return []   
    out.extend(self.postorderTraversal(root.left))
    out.extend(self.postorderTraversal(root.right))
    out = [root.val]
    return out

Python中append和extend的区别:

list1 = [1, 2, 3]

list2 = [2, 3, 10]

list3 = ['bg', [], 'ed']

# list1.append(list2)
# list1.append(list3)
# append:[1, 2, 3, [2, 3, 10], ['bg', [], 'ed']]

# list1.extend(list2)
# list1.extend(list3)
# extend:[1, 2, 3, 2, 3, 10, 'bg', [], 'ed']


深度遍历-方法2:迭代

前序遍历为例,从根节点开始,每次迭代弹出当前栈顶元素,并将其孩子节点压入栈中,先压右孩子再压左孩子。

在这个算法中,输出到最终结果的顺序按照 Top->BottomLeft->Right,符合前序遍历的顺序。

该算法只适用前序遍历。

def preorderTraversal(self, root: TreeNode) -> List[int]:
    if root is None:
	    	return []
    out = []
    stack = [root]
   	while stack:
	    	root = stack.pop()
        if root:
        out.append(root.val)
        stack.append(root.right)
        stack.append(root.left)
    return out

算法复杂度:

  • 时间复杂度:访问每个节点恰好一次,时间复杂度为 O(N) ,其中 N 是节点的个数,也就是树的大小。
  • 空间复杂度:取决于树的结构,最坏情况存储整棵树,因此空间复杂度是 O(N)

在这里插入图片描述

深度遍历-方法2.1:迭代优化

  • 上面的迭代代码是遇到节点直接把节点值存到输出数组里面,这种方法适合前序遍历,因为不用判断左孩子右孩子,所以不适合中序和后序遍历。
  • 上面的那种方法是把节点值输出然后再把右孩子左孩子依次压入栈中,那么我们应该也可以把根的节点值也一并的压入栈中。
  • 根据左孩子右孩子根的值压入栈中的顺序不同,从而实现前序、中序、后序的迭代遍历

参照递归的写法,使用栈这种数据结构(使用队列也可)

因为栈是先进后出,前序遍历是根、左、右
所以我们先把右孩子压进去,再压左孩子,最后再把根的值压进去
这样出栈的顺序就是根–>左孩子–>右孩子,就实现了前序遍历

# 前序遍历
stack.append(root.right)
stack.append(root.left)
stack.append(root.val)

之后,我们先把右孩子压进去,再压根的值,最后再把左孩子压进去
这样出栈的顺序就是左孩子–>根–>右孩子,就实现了中序遍历

# 中序遍历
stack.append(root.right)
stack.append(root.val)
stack.append(root.left)

同理,我们先把根的值压进去,再压右孩子,最后再把左孩子压进去
这样出栈的顺序就是左孩子–>右孩子–>根,就实现了后序遍历

# 后序遍历
stack.append(root.val)
stack.append(root.right)
stack.append(root.left)

之后判断何时可以将节点的值输出?

在栈中的数据类型一共有三种:Null树节点树节点值,而我们需要输出的值即为树节点值,所以我们只需要判断何时为树节点值即可;
也就是判断该节点不是树节点Null
if type(root) is not root_type and root is not None

# 以前序遍历为例
def preorderTraversal(self, root: TreeNode) -> List[int]:
    if root is None:
        return []
    stack, out = [root, ], []
    root_type = type(root)
    while stack:
        root = stack.pop()

        if type(root) is not root_type and root is not None:
            out.append(root)
            continue
            
        if root:
            stack.append(root.right)
            stack.append(root.left)
            stack.append(root.val)
    return out

Python改变一行代码实现二叉树前序、中序、后序的迭代遍历

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值