关于二叉树的前序遍历(preoder)、中序遍历(inorder)和后序遍历(postorder),实际上只需要记住:左子节点一定在右子节点的左边(左右),所谓前中后序遍历就是根节点的位置不同,前序是根左右,中序是左根右,后序是左右根。

python代码实现,先定义树节点的类如下:

class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = right

然后是前中后序的递归法实现,非常直观:

    # 前序遍历def preorderTraversal(self, root: TreeNode) -> List[int]:def preorder(root: TreeNode):if not root:returnans.append(root.val) # 根左右preorder(root.left)preorder(root.right)ans = list()preorder(root)return ans# 中序遍历def inorderTraversal(self, root: TreeNode) -> List[int]:def inorder(root: TreeNode):if not root:returninorder(root.left)  # 左根右ans.append(root.val)inorder(root.right)ans = list()inorder(root)return ans# 后序遍历def postorderTraversal(self, root: TreeNode) -> List[int]:def postorder(root: TreeNode):if not root:returnpostorder(root.left) # 左右根postorder(root.right)ans.append(root.val)ans = list()postorder(root)return ans

可以看到,实际上前中后序的递归法实现区别仅仅在于访问左右子节点和将根节点加入结果数组的顺序不同。

迭代法实现复杂一点,一般是使用一个栈,如下:

 # 前序遍历def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:ans = []if not root:return ansstack = []stack.append(root)while stack:node = stack.pop()if node:if node.right:                  # 右stack.append(node.right)if node.left:                 # 左stack.append(node.left)stack.append(node)                # 根stack.append(None)else:node = stack.pop()ans.append(node.val)return ans# 中序遍历def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:ans = []if not root:return ansstack = []stack.append(root)while stack:node = stack.pop()if node:if node.right:                 # 右stack.append(node.right)stack.append(node)               # 根stack.append(None)if node.left:                  # 左stack.append(node.left)else:node = stack.pop()ans.append(node.val)return ans# 后序遍历def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:ans = []if not root:return ansstack = []stack.append(root)while stack:node = stack.pop()if node:stack.append(node)              # 根stack.append(None)if node.right:                 # 右stack.append(node.right)if node.left:                    # 左stack.append(node.left)else:node = stack.pop()ans.append(node.val)return ans

可以看到,前中后序遍历的迭代写法是统一的,唯一区别就是中间的代码,只需要记住从下往上是根左右(前序)、左根右(中序)、左右根(后序)即可

对于N叉数,思路和二叉树是比较相似的。先看下N叉数的树节点定义:

# Definition for a Node.
class Node:def __init__(self, val=None, children=None):self.val = valself.children = children

589. N 叉树的前序遍历

class Solution:def preorder(self, root: 'Node') -> List[int]:def preorderTravel(root: 'Node'):if not root:returnans.append(root.val)for child in root.children:preorderTravel(child)ans = list()preorderTravel(root)return ans

递归写法,区别只是用for循环遍历所有子节点,而不是只遍历左右子节点。

class Solution:def preorder(self, root: 'Node') -> List[int]:if not root:return []stack = [root,]output = []            while stack:root = stack.pop()output.append(root.val)stack.extend(root.children[::-1])return output

迭代写法,这里注意入栈的是root.children[::-1],这样出栈时才是从左子树到右子树正确的顺序。

590. N 叉树的后序遍历

class Solution:def postorder(self, root: 'Node') -> List[int]:def postorderTravel(root: 'Node'):if not root:returnfor child in root.children:postorderTravel(child)ans.append(root.val)ans = list()postorderTravel(root)return ans

递归写法,相比前序遍历只是交换了一下位置,而N叉数没有中序遍历。

class Solution:def postorder(self, root: 'Node') -> List[int]:if not root:return []stack = [root,]output = []while stack:root = stack.pop()if root:output.append(root.val)for child in root.children:stack.append(child)return output[::-1]

迭代写法。

559. N 叉树的最大深度

class Solution:def maxDepth(self, root: 'Node') -> int:if not root:return 0elif root.children == []:return 1else:temp = list()for child in root.children:temp.append(self.maxDepth(child))return max(temp) + 1

递归,与二叉树的最大深度类似,注意要判断 root.children == [] 时深度为1。

还有一种遍历二叉树的方法,可以将空间复杂度降至O(1),名为Morris遍历,对其解释地最好的我觉得是这篇文章。

另外还有一种题,二叉树是存储成数组形式的,这时就要利用以下关系:根节点从0开始编号,对于任意一个节点 i,其左孩子编号为 2i+1,右孩子编号为 2i+2,代码如下:

#
# 对给定的二叉树依次完成前序,中序,后序遍历,并输出遍历结果
# @param input int整型一维数组 -1表示Nil节点
# @return int整型二维数组
#
# 定义一个二维列表
results = [[]for i in range(3)]
class Solution:def binaryTreeScan(self , input ):# write code here# 前序遍历def preOrder(root):if root<len(input):if input[root]!=-1:results[0].append(input[root])preOrder(root*2+1)preOrder(root*2+2)# 中序遍历def inOrder(root):if root<len(input):inOrder(root*2+1)if input[root]!=-1:results[1].append(input[root])inOrder(root*2+2)# 后序遍历def postOrder(root):if root<len(input):postOrder(root*2+1)postOrder(root*2+2)if input[root]!=-1:results[2].append(input[root])preOrder(0)inOrder(0)postOrder(0)return results

二叉树N叉数的前中后序遍历总结,python实现递归法和迭代法相关推荐

  1. 代码随想录——二叉树(一):前中后序遍历,层序遍历,翻转

    题目来自:https://www.programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80. ...

  2. 数据结构-二叉树(包含二叉树的层次建树、前中后序遍历、层次遍历解析及代码)

    目录 一.树与二叉树的原理解析 1.树的定义 2.树的结构和特点 3.二叉树的定义 4.树结点的数据结构 二.二叉树的层次建树 1.二叉树层次建树的原理及分析 2.完整代码 三.二叉树的前中后序遍历 ...

  3. 数据结构:二叉树的创建,打印前中后序遍历,节点个数,叶子节点数,销毁,第K层中节点的个数,查找值为x的节点

    二叉树遍历:按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次.(采用递归思想) 先序遍历:先遍历根节点,再遍历根节点的左子树,最后遍历根节点的右子树. 中序遍历:先遍历左 ...

  4. 二叉树(C++):创建,前中后序遍历(递归+非递归),获取叶子节点个数,获取树的高度

    文章目录 前言 创建二叉树 先序遍历 中序遍历 后序遍历 获取叶子节点个数 获取树的高度 测试代码 前言 现有如下二叉树: 关于二叉树的相关操作,我们能够发现二叉树从根节点到子节点,以及每个中间节点基 ...

  5. 二叉树的层序遍历和前中后序遍历代码 迭代/递归

    二叉树的层序遍历和前中后序遍历代码 迭代/递归 只记录代码.思路参考代码随想录:https://github.com/youngyangyang04/leetcode-master/blob/mast ...

  6. 二叉树前中后序遍历+刷题【中】【数据结构/初阶/C语言实现】

    文章目录 1. 二叉树基础操作 1.1 二叉树遍历 1.1.1 前序遍历 前序遍历(Pre-Order Traversal) 1.1.2 中序遍历 中序遍历(In-Order Traversal) 1 ...

  7. 二叉树前中后序遍历以及节点计算

    二叉树前中后序遍历以及节点计算 二叉树 分类 二叉链的数据结构 三叉链的数据结构 四种遍历方法 深度优先遍历:前中后序 广度优先遍历:层序遍历 计算 节点个数 叶子节点个数 树的高度 第k层的节点个数 ...

  8. [Leedcode][JAVA][第94/144/145题][前中后序遍历][递归][迭代][二叉树]

    [问题描述][] 前序遍历 先输出当前结点的数据,再依次遍历输出左结点和右结点 中序遍历 先遍历输出左结点,再输出当前结点的数据,再遍历输出右结点 后续遍历 先遍历输出左结点,再遍历输出右结点,最后输 ...

  9. 二叉树前中后序遍历的非递归实现以及层次遍历、zig-zag型遍历详解

    前言 二叉树的遍历是一个比较常见的问题,递归实现二叉树的前中后序遍历比较简单,但非递归实现二叉树的前中后序遍历相对有难度.这篇博客将详述如何使用非递归的方式实现二叉树的前中后序遍历,在进行理论描述的同 ...

最新文章

  1. 使用TensorRT和Jetson TX1 / TX2部署深度学习推理网络和深度视觉原语的指南 学习五
  2. 应用按home键无最近应用
  3. 功能Java示例 第4部分–首选不变性
  4. 【职场生活】跳槽离职要注意的那些坑?
  5. 深度学习TF—8.经典CNN模型—LeNet-5、VGG13、AlexNet、GoogLeNet、ResNet、DenseNet
  6. 大数据创业的门槛到底有哪些?
  7. 2021-2027全球及中国结构光源三维扫描仪行业研究及十四五规划分析报告
  8. GMAP.NET应用及离线地图加载
  9. 51单片机学习笔记7 -- 超声波测距
  10. scanf与空白字符
  11. python 爬取视频真实地址_python 爬取视频
  12. 利用DirectShow开发C#版的视频播放器
  13. 迅雷再换赛道锁定云计算 盈利能力待考
  14. Linux关于网络通信的命令
  15. 云宏信息科技股份有限公司
  16. TypeScript(八)装饰器
  17. 【数据库视频--概况
  18. mybatis的本质和原理
  19. 大数据分析练习-第八届泰迪杯A题-基于数据挖掘的上市公司高送转预测
  20. 调节latex表格中的字体大小

热门文章

  1. [转]小白都能看懂的softmax详解
  2. 【ArcGIS Pro微课1000例】0014:两种坐标系全国1km分辨率DEM下载地址(WGS84+Albers投影)
  3. 遥感空间尺度转换技术(升尺度和降尺度)
  4. 数学的意蕴与价值(建议收藏)
  5. 西北冬日的校园很静谧,却不失韵味,因为有我们美好的青春!
  6. C语言试题七之将函数字符串中的前导*号全部删除,中间和尾部的*号不删除。
  7. 数据结构之判断一棵树是不是满二叉树
  8. linux c之c语言符合标准的头文件和linux常用头文件
  9. Android之添加快捷方式(Shortcut)到手机桌面
  10. [python opencv 计算机视觉零基础到实战] 十八、用鼠标进行画画