二叉树的各种遍历(JS实现)

213 阅读2分钟

二叉树定义

这里以特殊的二叉搜索树来实现。

//树节点
class TreeNode {
    constructor(val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

//二叉搜索树
class BinarySearchTree {
    constructor() {
        this.root = null; //根节点
    }

    //插入值
    insert(val) {
        var newNode = new TreeNode(val);
        if (this.root === null) {
            this.root = newNode;
        } else {
            this.insertNode(this.root, newNode);
        }
    }

    //插入节点
    insertNode(node, newNode) {
        if (newNode.val < node.val) {
            if (node.left === null) {
                node.left = newNode;
            } else {
                this.insertNode(node.left, newNode);
            }
        } else {
            if (node.right === null) {
                node.right = newNode;
            } else {
                this.insertNode(node.right, newNode);
            }
        }
    }

    //获取根节点
    getRootNode() {
        return this.root;
    }

    //前序(根->左->右)
    preOrder(node) {
        if (node != null) {
            console.log(node.val);
            this.preOrder(node.left);
            this.preOrder(node.right);
        }
    }

    //中序(左->根->右)
    inOrder(node) {
        if (node != null) {
            this.inOrder(node.left);
            console.log(node.val);
            this.inOrder(node.right);
        }
    }

    //后序(左->右->根)
    postOrder(node) {
        if (node != null) {
            this.postOrder(node.left);
            this.postOrder(node.right);
            console.log(node.val);
        }
    }
}

const bst = new BinarySearchTree();
bst.insert(5);
bst.insert(3);
bst.insert(7);
bst.insert(2);
bst.insert(4);
bst.insert(6);
bst.insert(8);
      5
   /    \
  3       7
/   \    /  \
2   4   6    8

前序遍历

前序遍历:对于树中的任意节点来说,先打印这个节点,然后再打印它的左子树,最后打印它的右子树。

//递归实现
var preOrder = (root) => {
    let result = [];
    if (root === null) {
        return result;
    }
    helper(root, result);
    return result;
}
var helper = (root, result) => {
    if (root != null) {
        result.push(root.val);
        if (root.left != null) {
            helper(root.left, result);
        }
        if (root.right != null) {
            helper(root.right, result);
        }
    }
}

//迭代实现
var preOrder = (root) => {
    let result = [];
    if (root === null) {
        return result;
    }

    let stack = [];
    stack.push(root);
    while (stack.length > 0) {
        let node = stack.pop();
        result.push(node.val);
        if (node.right != null) {
            stack.push(node.right);
        }
        if (node.left != null) {
            stack.push(node.left);
        }
    }
    return result;
};


//测试
var root = bst.getRootNode();
console.log(preOrder(root)); //[5, 3, 2, 4, 7, 6, 8]

中序遍历

中序遍历:对于树中的任意节点来说,先打印它的左子树,然后再打印它本身,最后打印它的右子树。

//递归实现
var inOrder = (root) => {
    let result = [];
    if (root === null) {
        return result;
    }
    helper(root, result);
    return result;
}
var helper = (root, result) => {
    if (root != null) {
        if (root.left != null) {
            helper(root.left, result);
        }
        result.push(root.val);
        if (root.right != null) {
            helper(root.right, result);
        }
    }
}

//迭代实现
var inOrder = (root) => {
    let result = [];
    if (root === null) {
        return result;
    }

    let stack = [], curr = root;
    while (curr != null || stack.length > 0) {
        while (curr != null) {
            stack.push(curr);
            curr = curr.left;
        }
        curr = stack.pop();
        result.push(curr.val);
        curr = curr.right;
    }
    return result;
};

//测试
var root = bst.getRootNode();
console.log(inOrder(root)); //[2, 3, 4, 5, 6, 7, 8]

后序遍历

后序遍历:对于树中的任意节点来说,先打印它的左子树,然后再打印它的右子树,最后打印这个节点本身。

//递归实现
var postOrder = (root) => {
    let result = [];
    if (root === null) {
        return result;
    }
    helper(root, result);
    return result;
}
var helper = (root, result) => {
    if (root != null) {
        if (root.left != null) {
            helper(root.left, result);
        }
        if (root.right != null) {
            helper(root.right, result);
        }
        result.push(root.val);
    }
}

//迭代实现
var postOrder = (root) => {
    let result = [];
    if (root === null) {
        return result;
    }

    let stack = [];
    stack.push(root);
    while (stack.length > 0) {
        let node = stack.pop();
        result.unshift(node.val);
        if (node.left != null) {
            stack.push(node.left);
        }
        if (node.right != null) {
            stack.push(node.right);
        }
    }
    return result;
};

//测试
var root = bst.getRootNode();
console.log(postOrder(root)); //[2, 4, 3, 6, 8, 7, 5]

层次遍历

var levelOrder = (root) => {
    let result = [];

    if (root === null) {
        return result;
    }

    let q = [];
    q.push(root);

    while (q.length != 0) {
        let level = [], len = q.length;
        for (let i = 0; i < len; i++) {
            const node = q.shift();
            level.push(node.val);
            if (node.left != null) {
                q.push(node.left);
            }
            if (node.right != null) {
                q.push(node.right);
            }
        }
        result.push(level);
    }
    return result;
};

//测试
var root = bst.getRootNode();
console.log(levelOrder(root)); //[[5],[3,7],[2,4,6,8]]

之字遍历(锯齿形层次遍历)

var zigzagLevelOrder = (root) => {
    let result = [];

    if (root === null) {
        return result;
    }

    let q = [];
    q.push(root);

    let rev = true;

    while (q.length != 0) {
        let level = [], len = q.length;
        for (let i = 0; i < len; i++) {
            const node = q.shift();
            if (rev) {
                level.push(node.val);
            } else {
                level.unshift(node.val);
            }
            if (node.left != null) {
                q.push(node.left);
            }
            if (node.right != null) {
                q.push(node.right);
            }
        }
        result.push(level);
        rev = !rev;
    }
    return result;
};

var root = bst.getRootNode();
console.log(zigzagLevelOrder(root)); //[[5],[7,3],[2,4,6,8]]

LeetCode相关题

94.二叉树的中序遍历
leetcode-cn.com/problems/bi…

102.二叉树的层序遍历
leetcode-cn.com/problems/bi…

103.二叉树的锯齿形层次遍历
leetcode-cn.com/problems/bi…

107.二叉树的层次遍历 II
leetcode-cn.com/problems/bi…

144.二叉树的前序遍历
leetcode-cn.com/problems/bi…

145.二叉树的后序遍历
leetcode-cn.com/problems/bi…

987.二叉树的垂序遍历
leetcode-cn.com/problems/ve…