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);