打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Python改变一行代码实现二叉树前序、中序、后序的迭代遍历
  • 递归

  • 今天在做LeetCode的二叉树前序遍历题的时候,我看到题目是这样的:

    • 给定一个二叉树,返回它的前序遍历

    • 递归方法很简单,你可以通过迭代算法完成吗?

  • 我当时就不乐意了,你这也太高看我了,什么叫递归方法很简单?没想到我递归方法我也不会吧

  • 经过我冥思苦想终于把以前学数据结构的时候记忆拿回来了

  • 其实真的很简单,如下:

  • # 前序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 preorderTraversal(self, root):    if root is None: return []        out.extend(self.preorderTraversal(root.left))    out = [root.val]    out.extend(self.preorderTraversal(root.right))    return out# 后序def preorderTraversal(self, root):    if root is None: return []       out.extend(self.preorderTraversal(root.left))    out.extend(self.preorderTraversal(root.right))    out = [root.val]    return out
  • 这不是我这篇文章的重点,这只是前戏,还有就是递归真的很简单,我就不解释了

  • 迭代

  • 题目都说递归很简单了,让我用迭代的方法,那么我怎么能示弱呢?

  • 于是我想破我的小脑袋瓜也还是没有想出来,于是我看了题解。。。终于悟到其中的奥妙

  • 接着就有了下面的代码

  • def preorderTraversal(self, root):    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
  • 这也很简单,几乎就和官方题解一模一样,也没什么好解释的吧,但是我把这个方法理解之后看到一个C 大佬的题解说改变一行代码就实现前序、中序、后序的迭代遍历,反正具体的代码我也没看,我就想我用Python来实现一个

  • 于是我就想了想

    • 上面那套代码是遇到节点直接把它的值存到输出数组里面,这种方法适合前序遍历,但并不适合中序和后序遍历。

    • 上面的那种方法是把节点值输出然后再把右孩子和左孩子依次压入栈中,我就想我应该也可以把根节点的值也一并的压入栈中。

    • 根据左孩子、右孩子、根的值压入栈中的顺序不同,从而实现前序、中序、后序的迭代遍历

  • 因为栈是先进后出,前序遍历是根、左、右

    • 所以我们先把右孩子压进去,再压左孩子,最后再把根的值压进去

    • 这样出栈的顺序就是根-->左孩子-->右孩子,就实现了前序遍历

  • # 前序遍历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)
  • 综上

  • 前序遍历

  • def preorderTraversal(self, root):    if root is None:         return []    t = type(root)			# 保存树的类型    out = []				# 初始化输出数组    stack = [root]			# 将树压入栈中    while stack:			# 循环栈        root = stack.pop()	        # 根节点等于出栈的节点        if type(root) != t and root is not None:	# 如果此时root不为树并且不为空            out.append(root)				# 将这个数加入输出数组中            continue					# 结束本次循环        if root:      				        # 如果此时root是树            stack.append(root.right)			# 将右孩子压入栈            stack.append(root.left)			# 将左孩子压入栈            stack.append(root.val)			# 将根的值压入栈    return out
  • 中序遍历

  • def preorderTraversal(self, root):    if root is None:        return []    t = type(root)    out = []    stack = [root]    while stack:        root = stack.pop()        if type(root) != t and root is not None:            out.append(root)            continue        if root:                stack.append(root.right)            stack.append(root.val)					# 中序遍历            stack.append(root.left)    return out
  • 后序遍历

  • def preorderTraversal(self, root):    if root is None:        return []    t = type(root)    out = []    stack = [root]    while stack:        root = stack.pop()        if type(root) != t and root is not None:            out.append(root)            continue        if root:                stack.append(root.val)					# 后序遍历            stack.append(root.right)             stack.append(root.left)    return out
  • 以上就是我的思路和理解。

  • 从本质上来说,递归遍历二叉树和迭代遍历二叉树都是一样的,递归遍历二叉树是程序帮我们管理栈,迭代遍历二叉树是我们手动去维护栈。


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
一文弄懂二叉树三种遍历
二叉排序树的三种遍历方式和实现源代码
【小Y学算法】⚡️每日LeetCode打卡⚡️——40.二叉树的后序遍历
二叉树的非递归遍历 C语言版
二叉树的遍历;前序 中序 后序遍历二叉树;递归 非递归实现; 重建二叉树;编程之美重建二叉树
深入理解二叉树的非递归遍历
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服