递归很简单,不说了。
说说迭代。
逻辑上挺复杂的,看了代码才想出来,需要总结。
inorder traverse的要点在于,只要有left node,就往左走,没有的时候,才访问当前值,然后再以right node为新的开始,继续看是否有left node。
实现起来困难一点。
所有的LEFT NODE是倒叙访问,显然是使用stack。
说到只要有left node就加入到STACK,然后temp = temp.left.
一开始面临的问题是,假如到了一个NODE,有左NODE,已经访问过左边,现在是从右边回来,该如何知道此时我是往回走,而不是继续下去?
递归中访问回来,到上一层方程,位置不变,不是,用迭代,则是从ITERATOR的首部开始。
比如,递归是:
f(left)
visit current
f(right)
回去的位置正好是上一层的visit current。
迭代的话,比如1 2 3 4,4完了从STACK里POP出的是2,那么此时的2和一开始遍历的2该如何区分。。
public List<Integer> inorderTraversal(TreeNode root)
{
List<Integer> res = new ArrayList<Integer>();
if(root == null) return res;
Stack<TreeNode> stk = new Stack<TreeNode>();
TreeNode temp = root;
while(!stk.isEmpty() || temp != null)
{
while(temp != null)
{
stk.push(temp);
temp = temp.left;
}
temp = stk.pop();
res.add(temp.val);
if(temp.right != null) temp = temp.right;
else temp = null;
}
return res;
}
这里用stack是不是NULL来作为判定,是NULL就说明是回去的路上,while(temp !=null)里面的内容(添加左边NODE)就不运行。
回归的标准是,没有right node,就是NULL。(有的话,就以那个right node为节点,接续下去。)
二刷,或者三刷。。
还是递归不说了。
迭代也是大同小异,用stack
遍历的标志是res.add(curNode) 注意位置就行了。。
public class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) return res;
Stack<TreeNode> stk = new Stack<>();
TreeNode temp = root;
while (temp != null || !stk.isEmpty()) {
while (temp != null) {
stk.push(temp);
temp = temp.left;
}
temp = stk.pop();
res.add(temp.val);
temp = temp.right;
}
return res;
}
}