力扣关于树的题目(一)(各种遍历方式)

1. 二叉树的遍历方式

1. 前序遍历

1. 144. 二叉树的前序遍历

简单的前序遍历,两种方式,递归和非递归

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    let nums = [];
    const preOrder = (root) =>{
        if(!root) {
            return;
        }
        nums.push(root.val);
        preOrder(root.left);
        preOrder(root.right);
    }
    preOrder(root);
    return nums;
};

非递归的思路:利用栈结构,入栈的顺序是头右左

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    let nums = [];
    if(!root) {
        return nums;
    }
    let stack = [];
    stack.push(root);
    while(stack.length > 0) {
        let cur = stack.pop();
        nums.push(cur.val);
        if(cur.right) {
            stack.push(cur.right);
        }
        if(cur.left) {
            stack.push(cur.left)
        }
    }
    return nums;
};

2. 后序遍历

1. 145. 二叉树的后序遍历

单纯的后序遍历,分为递归和非递归两种

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function(root) {
    let nums = [];
    const postOrder = (root) => {
        if(!root) {
            return ;
        }

        postOrder(root.left);
        postOrder(root.right);
        nums.push(root.val);
    }
    postOrder(root);
    return nums;
};

非递归的思路:两个栈结构,入栈的顺序是头左右,出栈的时候放入另一个栈中,另一个栈pop出就是后序遍历的顺序

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function(root) {
    let nums = [];
    if(!root) {
        return nums;
    }
    let s1 = []
    let s2 =[]
    s1.push(root);
    while(s1.length > 0) {
        let cur = s1.pop();
        s2.push(cur);
        if(cur.left) {
            s1.push(cur.left);
        }
        if(cur.right) {
            s1.push(cur.right);
        }
    }
    while(s2.length > 0) {
        nums.push(s2.pop().val)
    }
    return nums;
};

3. 中序遍历

1. 94. 二叉树的中序遍历

单纯的中序遍历,分为递归和非递归两种

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

非递归的的思路:利用栈结构,对于每一个节点,需要左子树全部进栈之后才轮到右子树,因为在中序遍历中,如果一个节点要排出来,它的所有左节点都需要排在它前面

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function(root) {
    let res = [];
    
    if (root !== null) {
        let stack = [];
        while (stack.length > 0 || root !== null) {
            if (root !== null) {
                stack.push(root);
                root = root.left;
            }else {
                root = stack.pop();
                res.push(root.val);
                root = root.right;
            }
        }
    }
    
    return res;
};

4. 层序遍历

  1. 102. 二叉树的层序遍历

    单纯的层序遍历:利用队列的结构,在输出每一层的时候记录每一层的数量

    /**
     * @param {TreeNode} root
     * @return {number[][]}
     */
    var levelOrder = function(root) {
        let queue = [];
        let res = [];
        if (!root) {
            return res;
        }
        queue.push(root);
        while (queue.length) {
            let currentLevelSize = queue.length;
            let path = []
            for (let i = 0; i < currentLevelSize; i++) {
                let node = queue.shift();
                if (node) {
                    path.push(node.val);
                }
                if (node.left) {
                    queue.push(node.left);
                }
                if (node.right) {
                    queue.push(node.right);
                }
            }
            res.push(path)
        }
        return res;
    };
    
2. 103. 二叉树的锯齿形层序遍历

跟上一题的区别是,利用了双端队列的结构,插入的顺序不变,改变插入的位置,从而得到锯齿的效果

/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var zigzagLevelOrder = function(root) {
    let res = [];
    let queue = [];
    let isJi = false;
    if (!root) {
        return res;
    }
    queue.push(root);
    while (queue.length) {
        let currentLevelNodes = queue.length;
        let path = []
        for (let i = 0; i < currentLevelNodes; i++) {
            let node = queue.shift();
            if (isJi){
                path.push(node.val);
            }else {
                path.unshift(node.val)
            }
            if (node.right) {
                queue.push(node.right);
            }
            if (node.left) {
                queue.push(node.left);
            }
        }
        isJi = !isJi;
        res.push(path);
    }
    return res;
};
3. 513. 找树左下角的值
/**
 * @param {TreeNode} root
 * @return {number}
 */
var findBottomLeftValue = function(root) {
    let queue = [];
    queue.push(root);
    let levelSize = 1;
    let res;
    while (queue.length !== 0) {
        res = queue[0].val
        for (let i = 0; i < levelSize; i++) {
            let currentNode = queue.shift();
            if (currentNode.left) {
                queue.push(currentNode.left);
            }
            if (currentNode.right) {
                queue.push(currentNode.right);
            }
        }
        levelSize = queue.length;
    }
    return res;
};
posted @ 2022-04-21 16:19  kihyun  阅读(35)  评论(0编辑  收藏  举报