使用JS去實現一個BST(二叉查詢樹)

jinjiaxing發表於2019-04-19

BST(二叉查詢樹)

樹的概念

  • 根節點:沒有父節點
  • 節點:有父節點和子節點
  • 深度:當前節點的祖先節點數量
  • 高度:所有節點深度最大值
  • 子樹:由節點和它後代節點組成
  • 二叉樹:節點只能有兩個子節點
    • 左節點(比父節點小)
    • 右節點(比父節點大或等於)
    • 中序遍歷:左節點-節點-右節點(用於排序)
    • 先序遍歷:節點-左節點-右節點(用於列印結構化文件)
    • 後續遍歷:左節點-右節點-節點
function BinarySearchTree() {
    var Node = function (key) {
        this.key = key;
        this.left = null;
        this.right = null;
    }

    // 根節點
    var root = null;

    this.show = () => {
        console.log('root=', root);
    }

    // 插入
    this.insert = key => {
        let newNode = new Node(key);
        if (root == null) {
            root = newNode;
        } else {
            insertNode(root, newNode)
        }
    }
    let insertNode = (node, newNode) => {
        if (newNode.key < node.key) {
            if (node.left == null) {
                node.left = newNode;
            } else {
                insertNode(node.left, newNode);
            }
        } else {
            if (node.right == null) {
                node.right = newNode;
            } else {
                insertNode(node.right, newNode);
            }
        }
    }

    // 搜尋
    this.search = key => { searchNode(root, key) }
    let searchNode = (node, key) => {
        if (node == null) {
            return false;
        }
        if (key < node.key) {
            searchNode(node.left, key)
        } else if (key > node.key) {
            searchNode(node.right, key)
        } else {
            return true;
        }
    }
    // 刪除
    this.remove = key => { root = removeNode(root, key) }
    let removeNode = (node, key) => {
        if (node == null) {
            return null;
        }
        if (key < node.key) {
            node.left = removeNode(node.left, key);
        } else if (key > node.key) {
            node.right = removeNode(node.right, key);
        } else {
            // 沒有左右子節點的情況
            if (node.left == null && node.right == null) {
                node = null;
                return node;
            }
            // 只有一個子節點(如只有左節點或只有右節點)
            if (node.left == null && node.right !== null) {
                node = node.right;
                return node;
            } else if (node.right == null && node.left !== null) {
                node = node.left;
                return node;
            }
            // 兩個子節點的節點(左右節點都存在)
            if (node.left && node.right) {
                // 找到該節點右側的最小節點,替換當前節點
                let findRightMin = (node) => {
                    while (node && node.left !== null) {
                        node = node.left;
                    }
                    return node;
                }
                // 用右側最小節點去替換當前節點
                var aux = findMinNode(node.right);
                node.key = aux.key;
                node.right = removeNode(node.right, aux.key);
                // 同事需要刪除右側最小節點
                return node;
            }

        }

    }
    // 中序遍歷
    this.inOrder = () => {
        inOrderNode(root, (nodeKey) => { console.log(nodeKey) })
    }
    let inOrderNode = (node, callback) => {
        if (node !== null) {
            inOrderNode(node.left, callback);
            callback(node.key);
            inOrderNode(node.right, callback);
        }
    }
    // 前序遍歷
    this.preOrder = () => { preOrderNode(root, (nodeKey) => { console.log(nodeKey) }) }
    let preOrderNode = (node, callback) => {
        if (node !== null) {
            callback(node.key);
            preOrderNode(node.left, callback);
            preOrderNode(node.right, callback);
        }
    }
    // 後序遍歷
    this.postOrder = () => { postOrderNode(root, (nodeKey) => { console.log(nodeKey) }) }
    let postOrderNode = (node, callback) => {
        if (node !== null) {
            postOrderNode(node.left, callback);
            postOrderNode(node.right, callback);
            callback(node.key);
        }
    }
    // 樹的最小值
    this.min = () => { return minNode(root) }
    let minNode = (node) => {
        if (node) {
            while (node && node.left !== null) {
                node = node.left;
            }

            return node.key;
        }
        return null;
    }
    // 樹的最大值
    this.max = () => { return maxNode(root) }
    let maxNode = (node) => {
        if (node) {
            while (node && node.right !== null) {
                node = node.right;
            }

            return node.key;
        }
        return null;
    }


}
複製程式碼

相關文章