我们开始之前首先介绍一下关于二叉树和二叉搜索树
二叉树中的节点最多只能有两个子节点:一个是左侧的子节点,另一个是右侧的子节点。
- 二叉搜索树是二叉树的一种,但是它只允许你在左侧的节点存储比父节点小的值,在右侧的节点存储比父节点大的或者相等的值。
如下图
首先,声明它的结构:
function BinarySearchTree() {
var Node = function(key){
this.key = key; //存放该节点的值
this.left = null; //左侧的子节点
this.right = null; //右侧的子节点
};
var root = null; //根节点
}
然后,我们需要实现一些方法:
insert(key): 向树中插入新的键
search(key): 在树种查找一个键,如果节点存在,则返回true;如果不存在,则返回false
inOrderTraverse: 通过中序遍历方式遍历所有节点
preOderTraverse: 通过先序遍历的方式遍历所有节点
postOrderTraverse: 通过后序遍历的方式遍历所有节点
min: 返回树中的最小的键/值
max: 返回树中最大的键/值
remove(key): 从树种移除某个键
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.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.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 = node.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;
}
this.search = function(key){
return searchNode(root, key);
}
var searchNode = function(node, key){
if(node === null){
return false;
}else if(key < node.key){
return searchNode(node.left, key);
}else if(key > node.key){
return searchNode(node.right, key);
}else{
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{
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;
}
};
}
function printNode(value){
console.log(value);
}
var tree = new BinarySearchTree();
tree.insert(5);
tree.insert(4);
tree.insert(10);
tree.insert(3);
tree.insert(2);
tree.insert(9);
tree.insert(8);
tree.insert(6);
tree.insert(1);
tree.insert(7);
tree.inOrderTraverse(printNode);
tree.preOrderTraverse(printNode);
tree.postOrderTraverse(printNode);
console.log(tree.min());
console.log(tree.max());
tree.remove(6);
tree.postOrderTraverse(printNode);
输出结果如下:
1 2 3 4 5 6 7 8 9 10
5 4 3 2 1 10 9 8 6 7
1 2 3 4 7 6 8 9 10 5
1
10
1 2 3 4 7 8 9 10 5