🎃

02不统一的迭代遍历

2.迭代遍历

前序遍历

题目

递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中

思路

核心关键:因为要访问的元素和要处理的元素顺序是一致的,都是中间节点。
前序遍历是中左右,每次先处理的是中间节点,那么先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。
为什么要先加入 右孩子,再加入左孩子呢? 因为这样出栈的时候才是中左右的顺序。
动画如下:
notion image

TS实现

/** * Definition for a binary tree node. * class TreeNode { * val: number * left: TreeNode | null * right: TreeNode | null * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { * this.val = (val===undefined ? 0 : val) * this.left = (left===undefined ? null : left) * this.right = (right===undefined ? null : right) * } * } */ function preorderTraversal(root: TreeNode | null): number[] { const stack: TreeNode[] = []; const result: number[] = []; if (root === null) return result; stack.push(root); while(stack.length > 0) { const cur = stack.pop(); if (cur.right !== null) stack.push(cur.right); if (cur.left !== null) stack.push(cur.left); result.push(cur.val); } return result; };

中序遍历

题目

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3] 输出:[1,3,2]
示例 2:
输入:root = [] 输出:[]
示例 3:
输入:root = [1] 输出:[1]
提示:
  • 树中节点数目在范围 [0, 100] 内
  • 100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?

思路

中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的。
那么在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素。
动画如下:
notion image

TS实现

/** * Definition for a binary tree node. * class TreeNode { * val: number * left: TreeNode | null * right: TreeNode | null * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { * this.val = (val===undefined ? 0 : val) * this.left = (left===undefined ? null : left) * this.right = (right===undefined ? null : right) * } * } */ function inorderTraversal(root: TreeNode | null): number[] { const result: number[] = []; const stack: TreeNode[] = []; let cur: TreeNode = root; if (cur === null) return result; while(cur !== null || stack.length !== 0) { if (cur !== null) { stack.push(cur); cur = cur.left; } else { const top = stack.pop(); result.push(top.val); cur = top.right; } } return result; };

后序遍历

题目

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 
示例 1:
输入:root = [1,null,2,3]
输出:[3,2,1]
解释:
示例 2:
notion image
输入:root = [1,2,3,4,5,null,8,null,null,6,7,9]
输出:[4,6,7,5,2,9,8,3,1]
解释:
示例 3:
输入:root = []
输出:[]
示例 4:
输入:root = [1]
输出:[1]
提示:
  • 树中节点的数目在范围 [0, 100] 内
  • 100 <= Node.val <= 100
进阶:递归算法很简单,你可以通过迭代算法完成吗?

思路

再来看后序遍历,先序遍历是中左右,后序遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了,如下图:
notion image
所以后序遍历只需要前序遍历的代码稍作修改就可以了,代码如下:

TS实现

// 后序遍历(迭代法) function postorderTraversal(root: TreeNode | null): number[] { const stack: TreeNode[] = []; const result: number[] = []; if (root === null) return result; stack.push(root); while(stack.length > 0) { const cur = stack.pop(); result.push(cur.val); if (cur.left !== null) stack.push(cur.left); if (cur.right !== null) stack.push(cur.right); } return result.reverse();; };