【前端er每日算法】二叉树的前中序递归遍历以及迭代遍历

81 阅读1分钟

题目一 144. 二叉树的前序遍历

思路

前序遍历:左中右,递归最简单,迭代法借助栈,但是栈顺序是先进后出,所以栈的话先右孩子入栈,再左孩子入栈。

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    let result = [];
    const traversal = root => {
        if (!root) {
            return;
        }
        result.push(root.val);
        traversal(root.left);
        traversal(root.right);
    };
    traversal(root);
    return result;
};

// 迭代法
var preorderTraversal = function(root) {
    if (!root) {
        return [];
    }
    let result = [];
    const stack = [];
    stack.push(root);
    while (stack.length) {
        const node = stack.pop();
        result.push(node.val);
        if (node.right) {
            stack.push(node.right);
        }
        if (node.left) {
            stack.push(node.left);
        }
    }
    return result;
}

题目二 145. 二叉树的后序遍历

思路

左右中,和前序遍历类似,就是改了顺序

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function(root) {
    const result = [];
    const traversal = root => {
        if (!root) {
            return;
        }
        traversal(root.left);
        traversal(root.right);
        result.push(root.val);
    };
    traversal(root);
    return result;
};

var postorderTraversal = function(root) {
    const result = [];
    if (!root) {
        return result;
    }
    const stack = [root];
    while (stack.length) {
        const node = stack.pop();
        result.unshift(node.val);
        if (node.left) {
            stack.push(node.left);
        }
        if (node.right) {
            stack.push(node.right);
        }
    }
    return result;
}

题目三 94. 二叉树的中序遍历

思路

中左右,递归法和前面类似,不一样的是迭代法,需要用借助访问的指针,因为要先走到最左边的孩子,再访问中,右。循环判断,先往左走,如果不为空,则进栈,如果为空,则出栈,并且将右孩子进栈。

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function(root) {
    const result = [];
    const traversal = root => {
        if (!root) {
            return;
        }
        traversal(root.left);
        result.push(root.val);
        traversal(root.right);
    };
    traversal(root);
    return result;
};

var inorderTraversal = function(root) {
    if (!root) {
        return [];
    }
    const stack = [];
    const result = [];
    let node = root;
    while (node || stack.length) {
        if (node) {
            stack.push(node);
            node = node.left;
        } else {
            node = stack.pop();
            result.push(node.val);
            node = node.right;
        }
    }
    return result;
}

// 迭代2
var inorderTraversal2 = function(root) {
    if (!root) {
        return [];
    }
    const stack = [];
    const result = [];
    node = root;
    while (node || stack.length) {
        // 左子树都入栈
        while (node) {
            stack.push(node)
            node = node.left;
        }
        // 说明走到底了,开始访问根节点和右节点
        node = stack.pop();
        result.push(node.val);
        node = node.right;
    }
    return result;
}