二叉搜索树,也叫做二叉排序树。这种结构查找元素非常的高效。
在JS里面构建这种结构,有2种方法
1)通过嵌套的对象
2)通过嵌套的数组
下面我们给出嵌套的对象来实现这种结构
/*
二叉搜索树,二叉排序树,Binary Search Tree
这里我们使用嵌套的对象(nested object)
*/
function BinarySearchTree() {
var Node = function (key) {
this.key = key;
this.left = null;
this.right = null;
}
var root = null;
/*插入节点*/
this.insert = function (key) {
var new_node = new Node(key);
if(root == null) {
root = new_node;
} else {
insertNode(root, new_node);
}
function insertNode(parent, new_node) {
if(parent.key > new_node.key) {
if(parent.left == null) {
parent.left = new_node;
} else {
insertNode(parent.left, new_node);
}
} else {
if(parent.right == null) {
parent.right = new_node;
}else {
insertNode(parent.right, new_node);
}
}
}
}
/*
注意
实际上该函数应该是不存在的
为了测试方便引入的
为了防止对root 节点进行修改。
*/
this.getRoot = function () {
return root;
}
/*
搜索节点
使用哪种方法都可以
*/
// this.search = function (key) {
// if(root == null) {
// return false;
// }
// if(root.key == key) {
// return true;
// }
// if(root.key > key) {
// return searchTree(root.left);
// }
// if(root.key < key) {
// return searchTree(root.right);
// }
// function searchTree(parent) {
// if(parent == null) {
// return false;
// }
// if(parent.key == key) {
// return true;
// }
// if(parent.key > key) {
// return searchTree(parent.left); // 这里需要return
// }
// if(parent.key < key) {
// return searchTree(parent.right);
// }
// }
// }
this.search = function (key, parent) {
if(parent === null) { // 注意这里需要使用 === ,
return false; // 因为 undefined == null 显示的是true
}
var current = parent || root;
if(current == null) {
return false;
}
if(current.key == key) {
return true;
}
if(current.key > key) {
return this.search(key, current.left);
}
if(current.key < key) {
return this.search(key, current.right);
}
}
/*中序遍历*/
this.inOrderTraverse = function () {
if(root == null) {
return;
}
inOrderTraverseNode(root.left);
console.log(root.key);
inOrderTraverseNode(root.right);
/* Here is an auxiliary function */
function inOrderTraverseNode(parent) {
if(parent == null) {
return;
}
inOrderTraverseNode(parent.left);
console.log(parent.key);
inOrderTraverseNode(parent.right);
}
}
/*前序遍历*/
this.preOrderTraverse = function () {
if(root == null) {
return;
}
console.log(root.key);
preOrderTraverse(root.left);
preOrderTraverse(root.right);
/*Here is an auxiliary function*/
function preOrderTraverse(parent) {
if(parent == null) {
return;
}
console.log(parent.key);
preOrderTraverse(parent.left);
preOrderTraverse(parent.right);
}
}
/*后序遍历*/
this.postOrderTraverse = function () {
if(root == null) {
return;
}
postOrderTraverseNode(root.left);
postOrderTraverseNode(root.right);
console.log(root.key);
/*Here is an auxiliary function*/
function postOrderTraverseNode(parent) {
if(parent == null) {
return;
}
postOrderTraverseNode(parent.left);
postOrderTraverseNode(parent.right);
console.log(parent.key);
}
}
/*
返回BST树中的最小值
1) 使用递归
2)使用循环
*/
// this.min = function () {
// var current = root;
// while(current.left != null) {
// current = current.left;
// }
// return current.key;
// }
this.min = function () {
if(root == null) {
return;
}
return minNode(root);
function minNode(parent) {
if(parent.left == null) {
return parent.key;
}
return minNode(parent.left);
}
}
/*返回BST树中的最大值*/
// this.max = function () {
// var current = root;
// while(current.right != null) {
// current = current.right;
// }
// return current.key;
// }
this.max = function () {
if(root == null) {
return;
}
return maxNode(root);
function maxNode(parent) {
if(parent.right == null) {
return parent.key;
}
return maxNode(parent.right);
}
}
/*移除树中的节点*/
this.remove = function (key) {
root = removeNode(root, key);
/* Here is an auxiliary function */
function removeNode(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 findMinNode(node) {
if(node == null) {
return;
}
var current = node;
while(current.left != null) {
current = current.left;
}
return current;
}
}
}
}
var arr = [6, 20, 7, 9, 6, 2, 3, 1, 8, 4];
var bst = new BinarySearchTree();
for(var i=0; i<arr.length; ++i) {
bst.insert(arr[i]);
}
var root = bst.getRoot();
console.log(bst.search(6));