二叉树四种遍历的迭代实现
首先是三种深度优先遍历用同样模板的迭代方式来实现。
前序遍历: 中左右
中序遍历: 左中右
后序遍历:左右中
理解迭代算法的重点在于要理解每次获取一个节点的值的时候,是将这个节点看作 中间节点
来获取值的,而不是简单的获取左边值获取右边值获取中间值这种思路。
即获取所有节点值的过程都是先将这个节点看作一个中间节点然后根据遍历的顺序来决定先获取哪一侧的值。
迭代是通过栈实现,栈后进先出,因此将需要先遍历的节点最后入栈,后遍历的节点先入栈。
统一格式的迭代算法就是每次遍历到一个节点处,将它看作一个中间节点,然后根据遍历的顺序来设置其左右子节点和它本身入栈的顺序,将中间节点入栈后,添加一个空节点。
当读取到空节点时就表示下一个是中间节点,需要获取它的值。(因为每个节点在遍历的过程中都会有被看作中间节点的时候,所以会正确获取所有节点的值)
不是空节点时就表示当前遍历方式下还没有轮到获取节点值,即可能需要先遍历左右节点的值。
可以想作有一个指针,每次都指向中间节点,随着遍历顺序移动。
即使是叶子节点,也会被看作成中间节点,根据遍历顺序来将它的左右节点入栈,并添加空节点。因为不存在左右节点,所以最终会将这个叶子节点和一个空节点入栈,然后出栈读取到空节点,就可以获取这个叶子节点的值了。
前序遍历
前序遍历的顺序是中左右
所以入栈顺序是右左中
当读取到在中节点前的空节点时,获取它的值
代码:
var postorderTraversal = function(root) {
if (!root) return [];
const stack = [];
let res = [];
stack.push(root);
while(stack.length){
node = stack.pop();
// 不是空节点
if (node) {
if (node.right) stack.push(node.right);
if (node.left) stack.push(node.left