144 二叉树的前序遍历
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
**进阶:**递归算法很简单,你可以通过迭代算法完成吗?
递归算饭过于简单,不再赘述,我们直接看下迭代算法。
初始状态
将root节点入栈,然后now节点指向root节点的左子节点,发现为null。这个时候需要退回root节点(以下称1节点),但由于1节点我们已经遍历过了,所以直接可以进入1节点的右节点。(具有普适性,在前序遍历中我们当前节点的所有祖先节点均已被遍历)
我们出栈前一个节点(当前节点的父节点 ,然后去当前节点父节点的右子节点2节点),对该节点进行遍历操作(入栈,添加元素到数组)
然后根据前序遍历的性质,继续递归遍历2节点的左子树。
直到当前节点的左节点为null;然后跳转到当前节点的父亲节点的右节点(这里其实就是一个前->左->右的先序遍历过程)
发现3节点的右节点也为null,表明2节点的左子树已经被遍历完成,将2节点出栈,继续遍历其右子树。
最终,当前节点为null且栈中无可出栈元素,表示当前遍历已经完成。代码如下
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null){return res;}
Deque<TreeNode> stack = new ArrayDeque<>();
TreeNode now = root;
while(!stack.isEmpty() || now != null){
while(now != null ){
res.add(now.val);
stack.push(now);
now = now.left;
}
now = stack.pop();
now = now.right;
}
return res
}
}
总结:
-
整个先序遍历的过程就是 父节点->左子树->右子树的递归过程
-
栈是用来记录遍历顺序的信息的,如果当前节点为null,那么表示当前节点父节点的左子树已经遍历完成,需要退回到父亲节点,但是子节点是没有指向父节点的指针的,所以要依靠栈来记录退回父节点的指针。
-
整颗树遍历完成的条件:当前节点为null,且无父节点可回退。
-
注意
边界条件
,如果root=null,需要返回空数组。