给你二叉树的根节点
root
,返回它节点值的 前序 遍历。
知识点:二叉树递归
递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此递归过程,最重要的就是查看能不能讲原本的问题分解为更小的子问题,这是使用递归的关键。
而二叉树的递归,则是将某个节点的左子树、右子树看成一颗完整的树,那么对于子树的访问或者操作就是对于原树的访问或者操作的子问题,因此可以自我调用函数不断进入子树。
思路:
什么是二叉树的前序遍历?简单来说就是“根左右”,展开来说就是对于一颗二叉树优先访问其根节点,然后访问它的左子树,等左子树全部访问完了再访问其右子树,而对于子树也按照之前的访问方式,直到到达叶子节点。
从上述前序遍历的解释中我们不难发现,它存在递归的子问题:每次访问一个节点之后,它的左子树是一个要前序遍历的子问题,它的右子树同样是一个要前序遍历的子问题。那我们可以用递归处理:
- 终止条件: 当子问题到达叶子节点后,后一个不管左右都是空,因此遇到空节点就返回。
- 返回值: 每次处理完子问题后,就是将子问题访问过的元素返回,依次存入了数组中。
- 本级任务: 每个子问题优先访问这棵子树的根节点,然后递归进入左子树和右子树。
代码如下:
public List<Integer> preorderTraversal(TreeNode root){
List<Integer> res = new ArrayList<>();
if(root == null)
return res;
preorder(res,root);
return res;
}
public void preorder(List<Integer> list,TreeNode root) {
if(root == null)
return;
list.add(root.val);
preorder(list, root.left);
preorder(list, root.right);
}
法二:
迭代法+栈
- step 1:优先判断树是否为空,空树不遍历。
- step 2:准备辅助栈,首先记录根节点。
- step 3:每次从栈中弹出一个元素,进行访问,然后验证该节点的左右子节点是否存在,存的话的加入栈中,优先加入右节点。
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
Stack<TreeNode> s = new Stack<>();
if(root == null)
return list;
s.push(root);
while(!s.isEmpty()){
TreeNode cur = s.pop();
list.add(cur.val);
if(cur.right != null)
s.push(cur.right);
if(cur.left != null)
s.push(cur.left);
}
return list;
}