/**
* 二叉排序樹(Binary Sort Tree)又稱二叉查找樹(Binary Search Tree),亦稱二叉搜索樹。
* 左邊子節點的值 < 父節點的值 < 右邊子節點的值
* 包括的方法有:插入、遍歷、查詢、查詢父節點、右樹上最小節點、
* 前中後序遍歷、清空、刪除、是否爲空、求寬度、求深度
*/
function BinarySortTree(value){
this.root = null;
if(typeof value === "number"){
this.root = this.insert(value);
}else{
return false;
}
}
BinarySortTree.prototype = {
//創建節點
createNode: function(value){
return {
value:value,
left:null,
right:null
};
},
//插入一個新節點,如果沒有root就創建root
insert: function(value){
if(typeof value !== "number"){
return false;
}
var node = this.createNode(value);
if(!this.root){
this.root = node;
return this.root;
}else{
return this.insertNode(this.root, node);
}
},
//通過遞歸來插入
insertNode: function(fNode, newNode){
if(fNode.value>newNode.value){
if(fNode.left===null){
fNode.left = newNode;
return newNode;
}else{
return this.insertNode(fNode.left, newNode);
}
}else if(fNode.value<newNode.value){
if(fNode.right===null){
fNode.right = newNode;
return newNode;
}else{
return this.insertNode(fNode.right, newNode);
}
}else{
return false;
}
},
//查找第一個值相同的節點
findFirst: function(value){
console.log(this.root);
if(!this.root)return false;
return this.findFirstNode(this.root, value)
},
//採用的是前序查找 中>左>右
findFirstNode: function(node, value){
if(node === null)return false;
if(node.value === value)return node;
else if(node.value > value){
return this.findFirstNode(node.left, value);
}
else{
return this.findFirstNode(node.right, value);
}
},
//判斷空樹
isEmpty: function(){
if(this.root)return false;
return true;
},
//清空二叉樹
clear: function(){
this.clearTree(this.root);
this.root = null;
},
//清理某個子樹, 需要找到父節點,然後設爲null,不能直接將node設爲null
clearTree: function(node){
if(node === null)return;
this.clearTree(node.left);
this.clearTree(node.right);
var fNode = this.findFather(node);
if(fNode.left === node)fNode.left=null;
else if(fNode.right === node)fNode.right=null;
},
//尋找父節點
findFather: function(node){
return this.findFatherNode(this.root,node);
},
findFatherNode: function(fNode, node){
if(fNode===null)return false;
if(fNode.left === node || fNode.right === node)return fNode;
if(fNode.value>node.value)return this.findFatherNode(fNode.left, node);
else return this.findFatherNode(fNode.right, node);
},
//計算二叉樹深度
getDepth: function(){
return this.getTreeDepth(this.root);
},
//計算子樹深度
getTreeDepth: function(node){
if(node === null)return 0;
var leftDepth = this.getTreeDepth(node.left) + 1;
var rightDepth = this.getTreeDepth(node.right) + 1;
if(leftDepth>rightDepth)
return leftDepth;
return rightDepth;
},
//計算樹的寬度
getWidth: function(){
return this.getLeftTreeWidth(this.root)+this.getRightTreeWidth(this.root)-1;
},
//計算子樹寬度
getLeftTreeWidth: function(node){
if(node === null)return 0;
return 1+this.getLeftTreeWidth(node.left);
},
getRightTreeWidth: function(node){
if(node === null)return 0;
return 1+this.getRightTreeWidth(node.right);
},
//前序遍歷
preOrderTraverse: function(callback){
this.preOrderTraverseNode(this.root, callback);
},
preOrderTraverseNode: function(node, callback){
if(node === null)return;
//left
this.preOrderTraverseNode(node.left, callback);
//callback
callback(node.value);
//right
this.preOrderTraverseNode(node.right, callback);
},
//中序遍歷
inOrderTraverse: function(callback){
this.inOrderTraverseNode(this.root, callback);
},
inOrderTraverseNode: function(node, callback){
if(node === null)return;
//callback
callback(node.value);
//left
this.inOrderTraverseNode(node.left, callback);
//right
this.inOrderTraverseNode(node.right, callback);
},
//後序遍歷
postOrderTraverse: function(callback){
this.postOrderTraverseNode(this.root, callback);
},
postOrderTraverseNode: function(node, callback){
if(node === null)return;
//left
this.postOrderTraverseNode(node.left, callback);
//right
this.postOrderTraverseNode(node.right, callback);
//callback
callback(node.value);
},
//找到右樹的最小值
findRightMinNode: function(node){
if(node.left===null)return node;
else return this.findRightMinNode(node.left);
},
//移除
remove: function(value){
return this.removeNode(this.root, value);
},
removeNode: function(node, value){
var targetNode = this.findFirstNode(node, value);
var fNode = this.findFather(targetNode);
if(targetNode===this.root){
return false;//暫不考慮移除根節點情況
}
//target爲葉子節點
if(targetNode.left===null&&targetNode.right===null){
fNode.left === targetNode?fNode.left=null:fNode.right=null;
return true;
}
//target只有一個子節點
if(targetNode.left===null&&targetNode.right){
fNode.left === targetNode?fNode.left=targetNode.right:fNode.right=targetNode.right;
delete targetNode.value;
delete targetNode.right;
delete targetNode.left;
return true;
}
if(targetNode.right===null&&targetNode.left){
fNode.left === targetNode?fNode.left=targetNode.left:fNode.right=targetNode.left;
delete targetNode.value;
delete targetNode.right;
delete targetNode.left;
return true;
}
//target有兩個子節點
var minNode = this.findRightMinNode(targetNode.right);
targetNode.value = minNode.value;
return this.removeNode(targetNode.right, targetNode.value);
}
};
var root = new BinarySortTree(0);
root.insert(1);
root.insert(2);
root.insert(8);
root.insert(4);
root.insert(9);
root.insert(-7);
root.insert(-1);
root.insert(-8);
console.log(root);
JavaScript數據結構之 二叉排序樹
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.