《學習JavaScript數據結構與算法》(第8章)(平衡二叉樹代碼實現)

平衡二叉樹JS代碼實現

var Tree = function() {
    var Node = function(value) {
        this.value = value;
        this.left = null;
        this.right = null;
    }
    var root = null;    //根節點  
    /*
    插入節點:
    一、樹爲空
    二、樹不爲空 -> 比較(小於 -> 往左走;大於 -> 往右走)
    */ 
    this.insert = function(value) {
        var newNode = new Node(value);
        if(root == null) { //空樹          
            root = newNode;
        }else{//樹非空           
            insertNode(root, newNode);
        }
    };

    //自平衡樹插入新節點
    var insertNode = function(node,newNode) {
        if(node == null) {
            node = newNode;
        //向左走(向左子樹拆入新節點,且節點的值小於其左子節點時,應該進行LL旋轉。不然,進行LR旋轉)
        }else if(newNode.value < node.value) {
            node.left = insertNode(node.left, newNode);
            if(node.left == null) {
                node.left = newNode;
                if(heightNode(node.left) - heightNode(node.right) > 1) {
                    if(newNode.value < node.left.value) {
                        node = rotationLL(node);
                    }else{
                        node = rotationLR(node);
                    }
                }
            }else if(node.left !== null){
                if(heightNode(node.left) - heightNode(node.right) > 1) {
                    if(newNode.value < node.left.value) {
                        node = rotationLL(node);
                    }else{
                        node = rotationLR(node);
                    }
                }
            }
        //向右走(向右子樹拆入新節點,且節點的值大於其右子節點時,應該進行RR旋轉。不然,進行RL旋轉)
        }else if(newNode.value > node.value) {
            node.right = insertNode(node.right, newNode);
            if(node.right == null) {
                node.right = newNode;
                if(heightNode(node.right) - heightNode(node.left) > 1) {
                    if(newNode.value > node.right.value) {
                        node = rotationRR(node);
                    }else{
                        node = rotationRL(node);
                    }
                }
            }else if(node.right !== null) {
                if(heightNode(node.right) - heightNode(node.left) > 1) {
                    if(newNode.value > node.right.value) {
                        node = rotationRR(node);
                    }else{
                        node = rotationRL(node);
                    }
                }
            }
        }
        return node;
    };
    var heightNode = function(node) {
        if(node === null) {
            return -1;
        }else{
            return Math.max(heightNode(node.left), heightNode(node.right)) + 1;
        }
    };
    //RR向左的單旋轉
    var rotationRR = function(node) {
        var tmp = node.right;
        node.right = tmp.left;
        tmp.left = node;
        return tmp;
    };
    //LL向右的單旋轉
    var rotationLL = function(node) {
        var tmp = node.left;
        node.left = tmp.right;
        tmp.right = node;
        return tmp;
    };
    //LR向右的雙旋轉
    var rotationLR = function(node) {
        node.left = rotationRR(node.left);
        return rotationLL(node);
    }
    //RL向左的雙旋轉
    var rotationRL = function(node) {
        node.right = rotationLL(node.right);
        return rotationRR(node);
    };

    //遍歷節點
    this.traverse = function(callback) {
        traverse(root, callback);
    };
    var traverse = function(node, callback) {
        if(node == null) return;
        //(後續遍歷)左右中;(中序遍歷)左中右;(前序遍歷)中左右
        traverse(node.left, callback);
        traverse(node.right, callback);
        callback(node.value);
    };
    
    //顯示樹
    this.getRoot = function() {
        return root;
    };
}

測試代碼:node

var t = new Tree;
var print = function(value) {
    console.log('value -',value)   
};

t.insert(11);
t.insert(8);
t.insert(4);
t.insert(9);
t.traverse(print);
相關文章
相關標籤/搜索