二叉树的迭代遍历(前中后序)

88 阅读3分钟

前言

之前学习了二叉树的递归遍历,接下来学习下二叉树的迭代遍历。

二叉树的前序遍历-迭代法

题目描述

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

示例:

image.png

输入: root = [1,null,2,3]
输出: [1,2,3]

思路

  1. 按照栈的思路来处理这类问题,前序遍历的顺序为中左右,这里我们推入栈中的顺序为中右左,因为栈的特点为先进后出
  2. 结束遍历的条件为栈空

代码

var preorderTraversal = function(root) {
   // 栈,结果数组
   let stack=[],result=[];

   //将根节点推入栈中
   stack.push(root);

   //当栈不为空时,按照 中右左 的顺序执行逻辑
   while(stack.length!=0){

       let item=stack.pop();

       if(item==null){
           continue;
       }

       result.push(item.val);
       if(item.right)stack.push(item.right);
       if(item.left) stack.push(item.left);
   }

   return result;
};

结果

image.png

二叉树的后序遍历-迭代法

题目描述:

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 示例 1:

image.png

输入: root = [1,null,2,3]
输出: [3,2,1]

思路

  1. 后续遍历的顺序为左右中,我们首先得到的便是节点,所以直接按照左右中的 顺序来做,不好做。
  2. 左右中——中右左,如果我们按照中右左的顺序来遍历,遍历结束后将结果反转便可以得到左右中的结果了。
  3. 逻辑顺序为中右左,入栈顺序为中左右,因为栈的特点为:先进后出

代码

var postorderTraversal = function(root) {
    // 定义栈,结果数组
    let stack=[],result=[];
    stack.push(root);

    // 以栈是否为空作为是否结束遍历的条件。
    while(stack.length!=0){
        //弹出栈顶元素
        let item=stack.pop();
        //若栈顶元素为null,跳过
        if(item==null) continue;

        // 不为空,将栈顶元素的值放入结果数组中
        result.push(item.val);
       
       // 按照左右的顺序,将节点推入栈中
        if(item.left) stack.push(item.left);
        if(item.right) stack.push(item.right);
    }

    // 反转结果数组,并返回。
    return result.reverse();
};

结果

image.png

二叉树的中序遍历-迭代法

题目描述

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1:

image.png

输入: root = [1,null,2,3]
输出: [1,3,2]

思路

  1. 中序遍历的顺序为左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中)。
  2. 需要一个指针去找到左子树的叶子节点,也就是要找到最深层的左节点。
  3. 结束遍历的条件为:栈为空并且指针为null

代码

var inorderTraversal = function(root) {
    // 定义栈,结果数组,当前指针
    let stack=[],result=[],cur=root;
    // 当栈不为空或者cur!=null时
    while(stack.length!=0||cur!=null){
        // 如果cur不为null
        if(cur){
            //将cur推入栈中,并且cur指向cur的left
            stack.push(cur);
            cur=cur.left;
        }
        else{
            // 否则,弹出栈顶元素,cur指向栈顶元素。
            cur=stack.pop();
            result.push(cur.val);
            // 判断栈顶元素是否有右节点
            cur=cur.right;
        }
    }

    return result;
};

结果:

image.png

总结

二叉树的遍历分为:迭代遍历和递归遍历,相对而言递归好理解一点,但迭代遍历也不难,关键点在于:采用栈的思想,并弄清楚几种遍历的顺序,理清思路。