算法-前序遍历二叉树

159 阅读2分钟

这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

一、leetcode第144题二叉树的前序遍历

题目:给你二叉树的根节点 root ,返回它节点值的前序遍历。

二、递归实现

var preorderTraversal = function(root,arr=[]) {
    if(root) {
        //先遍历自己,再遍历左右子树
        arr.push(root.val);
        preorderTraversal(root.left,arr);        preorderTraversal(root.right,arr);
    }
    return arr;
}

思路:

  • 因为需要递归,所以需要arr是收集最终结果的,最后return回去。
  • 判断当前节点是否存在
  • 然后先处理自己再处理左右节点。

提示:上一章讲过二叉树的几种遍历形式,有前序遍历、中序遍历和后序遍历,上面是通过递归的方式实现的,并且是前序的方式,如果是需要中序遍历或者后序就把arr.push(root.val)的位置调换到下面就可以实现三种遍历的方式,递归的形式三种前序中序后序的区别很小,只是更换位置。

三、迭代的方式实现前序遍历

var preorderTraversal = function(root) {
    let result = [];
    let stack = [];
    let cur = root;
    while(cur || stack.length > 0) {
        while(cur) {//这里左子树处理完             result.push(cur.val);//先处理自己             stack.push(cur);//后面要通过current找到他的right节点              cur = cur.left        }    
        cur = stack.pop();        cur = cur.right;    }    
    return result;
}

思路:

  1. 用循环的方式迭代遍历,因为想用前序遍历的方式实现,就需要用一个stack进行存储
  2. 然后自己入栈,用stack把自己缓存起来
  3. 再让left节点入栈,直到left节点为空,把left节点遍历到头
  4. 因为left节点遍历完了,再把上一个进入缓存的节点pop出来,再让右节点遍历一遍,让right节点为目标节点入栈

四、总结

这就是两种方式实现前序遍历,总的来说递归的方式是最简单的,特别是可以直接实现前序中序后序三种方式,只是变换位置。而迭代的方式就比较麻烦,需要把自己缓存起来,再考虑左右节点是否有子节点,再进行出栈入栈的问题,最终再返回结果。

练完前序的遍历方式,可以再去leetcode上练习几个中序和后续的遍历方式,比如94题中序遍历和第145题后续遍历方式,并且分别用递归和迭代循环实现。