二叉树三种遍历的递归和迭代解法(2)

和先序遍历略有不同的是,先序遍历是先遍历父节点,所以父节点的value值要在入栈的时候就放入ans数组,而后序遍历是最后遍历父节点,所以当父节点出栈时(此时左右子树都已经遍历完毕),把节点的value值放入ans数组即可:

var postorderTraversal = function(root) { if (!root) return []; var stack = [] // 栈模拟 , ans = []; stack.push(root); while (stack.length) { var elem = stack[stack.length - 1]; if (elem.left) { stack.push(elem.left); elem.left = null; } else if (elem.right) { stack.push(elem.right); elem.right = null; } else { var a = stack.pop(); ans.push(a.val); } } return ans; };

中序遍历

中序遍历是三大遍历里最复杂的。先序遍历是先遍历父节点,所以节点入栈时存储value值,后序遍历是最后遍历父节点,所以节点出栈时存储value值,中序遍历呢?

在leetcode中,中序遍历这题比先序和后序多了一个tag - hash table,而如何hash也正是本题难点。中序遍历是在父节点的左子树遍历完后,将父节点的value值存入ans数组的,那么如何判断左子树已经遍历完了呢?

比如下面这棵二叉树:

1 / \ 2 5 / \ 3 4

当遍历到 2 这个节点时,它有左节点,按照先序和后序遍历的做法,将左节点入栈,同时将 2 所在节点的left置为null,当节点 3 出栈后,判断 2 节点的左右子节点,这时发现左节点为null,说明已经遍历过了,于是 value=2 存入ans数组,然后 4 所在节点入栈,然后 4 再出栈,这时栈顶元素又是2,而这时再次判断左右子节点,发现左子节点为null,认为左子节点遍历过了,value=2再次存入ans数组!看到这里,你或许有点眉目了,我们不能用置为null来表示节点已经遍历,而应该用正确的hash方式,这里我用 elem.left=1 表示elem的左节点已经被遍历过了,用 elem.left=0 表示elem节点所在的值已经存入ans数组了。

var inorderTraversal = function(root) { if (!root) return []; var stack = [], ans = []; stack.push(root); while (stack.length) { var elem = stack[stack.length - 1]; if (elem.left === 1) { elem.left = 0; ans.push(elem.val); } else if (elem.left) { stack.push(elem.left); elem.left = 1; } else if (elem.left === null) { elem.left = 1; } else if (elem.right) { stack.push(elem.right); elem.right = null; } else { stack.pop(); } } return ans; };

二叉树的常见问题及其解决程序

【递归】二叉树的先序建立及遍历

Java中实现的二叉树结构

【非递归】二叉树的建立及遍历

二叉树递归实现与二重指针

二叉树先序中序非递归算法

轻松搞定面试中的二叉树题目

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/0316b5174fa641053efbccc59b177d18.html