二叉樹基本算法


僅供JavaScript刷題參考用。

二叉查找樹和平衡二叉樹

完全二叉樹

若設二叉樹的深度為k,除第 k 層外,其它各層 (1~k-1) 的結點數都達到最大個數,第k 層所有的結點都連續集中在最左邊,這就是完全二叉樹。

其它樹:滿二叉樹、完美二叉樹、哈弗曼樹、二叉查找樹BST、平衡二叉樹AVL
了解:紅黑樹,是一種特殊的二叉樹。這種樹可以進行高效的中序遍歷

建立

創建BinarySearchTree類。首先,聲明它的結構:

(注意,BinarySearchTree是個類,后面所有函數都定義在該結構體內)

function BinarySearchTree() {
    //私有的輔助函數
    var Node = function(key){
        this.key = key;
        this.left = null;
        this.right = null;
    };
    //聲明一個私有變量以控制此數據結構的第一個節點。在樹中,它不是頭節點,而是根元素
    var root = null;
}

插入

this.insert = function(key){
    var newNode = new Node(key);
    if (root === null){
        root = newNode;
    } else {
        insertNode(root,newNode);
    }
};
// 私有的輔助函數
var insertNode = function (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.remove = function (key) {
    root = removeNode(root, key);
};
var removeNode = function (node, key) {
    if (node === null) {
        return null;
    }
    if (key < node.key) {
        node.left = removeNode(node.left, key);
        return node;
    } else if (key > node.key) {
        node.right = removeNode(node.right, key);
        return node;
    } else { //鍵等於node.key
        //第一種情況——一個葉節點
        if (node.left === null && node.right === null) {
            node = null;
            return node;
        }
        //第二種情況——一個只有一個子節點的節點
        if (node.left === null) {
            node = node.right;
            return node;
        } else if (node.right === 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.search = function (key) {
    return searchNode(root, key);
};
var searchNode = function (node, key) {
    if (node === null) {
        return false;
    }
    if (key < node.key) {
        return searchNode(node.left, key);
    } else if (key > node.key) {
        return searchNode(node.right, key);
    } else {
        return true;
    }
};

尋找最大值

this.max = function () {
    return maxNode(root);
};
var maxNode = function (node) {
    if (node) {
        while (node && node.right !== null) {
            node = node.right;
        }
        return node.key;
    }
    return null;
};

尋找最小值

this.min = function () {
    return minNode(root);
};
var minNode = function (node) {
    if (node) {
        while (node && node.left !== null) {
            node = node.left;
        }
        return node.key;
    }
    return null;
};

遍歷

✔先序

this.preOrderTraverse = function (callback) {
    preOrderTraverseNode(root, callback);
};
var preOrderTraverseNode = function (node, callback) {
    if (node !== null) {
        callback(node.key);
        preOrderTraverseNode(node.left, callback);
        preOrderTraverseNode(node.right, callback);
    }
};

✔中序

this.inOrderTraverse = function (callback) {
    inOrderTraverseNode(root, callback);
};
var inOrderTraverseNode = function (node, callback) {
    if (node !== null) {
        inOrderTraverseNode(node.left, callback);
        callback(node.key);
        inOrderTraverseNode(node.right, callback);
    }
};

✔后序

this.postOrderTraverse = function (callback) {
    postOrderTraverseNode(root, callback);
};
var postOrderTraverseNode = function (node, callback) {
    if (node !== null) {
        postOrderTraverseNode(node.left, callback);
        postOrderTraverseNode(node.right, callback);
        callback(node.key);
    }
};

✔深度優先(DFS)

在二叉樹中,DFS就相當於先序遍歷

✔廣度優先(BFS)/層次遍歷

利用隊列來模擬,就很容易了

this.bfsTraverse = function (callback) {
    bfsTraverseNode(root, callback)
}
var bfsTraverseNode = function (root, callback) {
    var queue = []
    if(root){
        queue.push(root)
    }
    while(queue.length){
        var node = queue.shift()
        callback(node.key)
        if(node.left){
            queue.push(node.left)
        }
        if(node.right){
            queue.push(node.right)
        }
    }
}

線索化二叉樹


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM