function BinarySearchTree(){
var Node = function(key){
this.key = key;
this.left = null;
this.right = null;
};
var root = null; //根元素
//在树中插入一个新的键
this.insert = function(key){
//创建用来表示新节点的Node实例
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方法继续找到树的下一层
insertNode(node.left, newNode);
}
}else{
//如果节点的键比当前节点的键大,同时当前节点没有右侧子节点,就在那里插入新的节点
if(node.right === null){
node.right = newNode;
}else{
//如果又右侧子节点,递归调用insetNode方法
insertNode(node.right,newNode);
}
}
};
//中序遍历所有节点
//接受一个回调函数作为参数
this.inOrderTraverse = function(callback){
inOrderTraverseNode(root,callback);
};
var inOrderTraverseNode = function(node,callback){
//检查以参数形式传入的节点是否为null
if(node !== null){
//递归调用相同的函数来访问左侧子节点,对这个节点进行一些操作(callback)
inOrderTraverseNode(node.left,callback);
callback(node.key);
//访问右侧子节点
inOrderTraverseNode(node.right,callback);
}
};
//先序遍历
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.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);
}
};
//寻找树的最小键
this.min = function(){
//传入树的根节点
return minNode(root);
};
var minNode = function(node){
if(node){
//遍历树的左边,知道找到输的最下层(最左端)
while(node &&node.left !== null){
node = nnode.left;
}
return node.key;
}
return null;
};
//寻找树的最大键
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;
};
//声明search方法
this.search = function(key){
return searchNode(root,key);
};
var searchNode = function(node,key){
//验证作为参数传入的node是否合法(不是null)如果是null,返回false
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{
//要找的键和当前节点的键相等,返回true
return true;
}
};
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{
//找到了要找的键,处理3种不同情况
//1.移除一个叶节点
if(node.left ===null&&node.right ===null){
node = null;
return null;
}
//2.移除有一个左侧或右侧子节点的节点
if(node.left === null){
node = node.right;
return node;
} else if(node.right ===null){
node = node.left;
return node;
}
//3.移除有两个子节点的节点
var aux = findMinNode(node.right);
node.key = aux.key;
node.right = removeNode(node.right,aux.key);
return node;
}
};
}
var tree = new BinarySearchTree();
tree.insert(11);
tree.insert(7);
tree.insert(15);
tree.insert(5);
tree.insert(3);
tree.insert(9);
tree.insert(8);
tree.insert(10);
tree.insert(13);
tree.insert(12);
tree.insert(14);
tree.insert(20);
tree.insert(18);
tree.insert(25);
tree.insert(6);
//创建一个回调函数
function printNode(value){
console.log(value);
}
//调用inOrderTraverse方法并将回调函数作为参数传入
//tree.inOrderTraverse(printNode);
//调用preOrderTraverse
//tree.preOrderTraverse(printNode);
//调用postOrderTraverse
//tree.postOrderTraverse(printNode);
console.log(tree.search(1)?'found':'not found');
console.log(tree.search(8)?'found':'not found');
JavaScript二叉搜索树
最新推荐文章于 2022-07-15 16:12:04 发布