定义:二叉查找树又被称为二叉搜索树。设x为二叉查找树中的一个结点,x结点包含关键字value,结点x的key值计为value[x]。如果y是x的左子树中的一个结点,则value[y]<=value[x];如果y是x的右子树的一个结点,则value[y]>=value[x]。
在二叉查找树中:
(1)若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值。
(2)任意结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值。
(3)任意结点的左、右子树也分别为二叉查找树。
(4)没有键值相等的结点。
//封装二叉树的方法
function BinarySearchTree() {
//封装节点
function Node(key) {
this.key = key;
this.left = null;
this.right = null;
}
//属性
this.root = null;
//方法
//二叉树插入数据的方法
BinarySearchTree.prototype.insert = function (key) {
//1.根据key创建新的节点
var newNode = new Node(key);
//2.判断根节点是否有值
if (this.root === null) {//根节点没有值,就先新建根节点
this.root = newNode;
} else {
//调用插入节点的方法
this.insertNode(this.root, newNode);
}
};
//类内部使用的方法,插入节点
BinarySearchTree.prototype.insertNode = function (node, newNode) {
//将之前的节点与新节点做比较
if (newNode.key < node.key) {
//新节点的key小于上一节点的key,向左查找
//如果旧节点的左孩子为空,将新节点插入到此处
//否则递归向左查找直到旧节点的左孩子为空
if (node.left === null) {
node.left = newNode;
} else {
this.insertNode(node.left, newNode);
}
} else {//向右查找
if (node.right === null) {
node.right = newNode;
} else {
this.insertNode(node.right, newNode)
}
}
};
//树的遍历
//1.先序遍历
BinarySearchTree.prototype.preOrderTraversal = function () {
this.preOrderTraversalNode(this.root)
};
BinarySearchTree.prototype.preOrderTraversalNode = function (node) {
if (node !== null) {
//1.处理先序遍历经过的节点
preResult += node.key + ' ';
//2.查找经过节点的左子节点
this.preOrderTraversalNode(node.left);
//3.查找经过节点的右子节点
this.preOrderTraversalNode(node.right);
}
};
//2.中序遍历
BinarySearchTree.prototype.midOrderTraversal = function () {
this.midOrderTraversalNode(this.root);
};
BinarySearchTree.prototype.midOrderTraversalNode = function (node) {
if (node !== null) {
//1.查找经过节点的左子节点
this.midOrderTraversalNode(node.left);
//2.处理节点
midResult += node.key + ' ';
//3.查找经过节点的右子节点
this.midOrderTraversalNode(node.right);
}
};
//3.后序遍历
BinarySearchTree.prototype.postOrderTraversal = function () {
this.postOrderTraversalNode(this.root);
};
BinarySearchTree.prototype.postOrderTraversalNode = function (node){
if (node !== null) {
//1.查找经过节点的左子节点
this.postOrderTraversalNode(node.left);
//2.查找经过节点的右子节点
this.postOrderTraversalNode(node.right);
//3.处理节点
postResult += node.key + ' ';
}
};
//寻找最值
//寻找最大值
BinarySearchTree.prototype.max = function () {
//从根节点开始
var node = this.root;
var key = null;
//依此向右不断的查找,直到节点为null
while (node) {
key = node.key;
node = node.right;
}
return key;
};
//寻找最小值
BinarySearchTree.prototype.min = function () {
//从根节点开始
var node = this.root;
var key = null;
//依此向左不断的查找,直到节点为null
while (node) {
key = node.key;
node = node.left;
}
return key;
};
//使用递归 搜索特定的值
BinarySearchTree.prototype.search_DG = function (key) {
return this.searchNode_DG(this.root, key);
};
BinarySearchTree.prototype.searchNode_DG = function (node, key) {
//1.如果传入的node为null,退出递归
if (node === null) {
return false;
}
//2.判断node节点的值和传入key大小
if (node.key > key) {
return this.searchNode_DG(node.left, key);
} else if (node.key < key) {
return this.searchNode_DG(node.right, key);
} else {//相同,说明找到了key
return true;
}
};
//使用循环 搜索特定的值
BinarySearchTree.prototype.search_Loop = function (key) {
var node = this.root;
while (node) {
if (key < node.key) { //向左查找
node = node.left;
} else if (key > node.key) {
node = node.right;
} else {
return true;
}
}
return false; //while循环退出=>node为null=>查找失败
}
}
下面对代码进行验证:
//创建二叉搜索树 BinarySearchTree
var bst = new BinarySearchTree();
//2.插入数据
bst.insert(11);
bst.insert(7);
bst.insert(15);
bst.insert(5);
bst.insert(3);
bst.insert(9);
bst.insert(8);
bst.insert(10);
bst.insert(13);
bst.insert(12);
bst.insert(14);
bst.insert(20);
bst.insert(18);
bst.insert(25);
bst.insert(6);
preResult = '';
bst.preOrderTraversal();//测试先序遍历
console.log('先序遍历', preResult);
midResult = '';
bst.midOrderTraversal();//测试中序遍历
console.log('中序遍历', midResult);
postResult = '';
bst.postOrderTraversal();//测试后序遍历
console.log('后序遍历', postResult);
//测试最值
console.log('最大值', bst.max());
console.log('最小值', bst.min());
//测试查找特定值
console.log(bst.search_DG(12));
console.log(bst.search_Loop(13));
console.log(bst.search_Loop(2));
输入的节点数据依次是11 7 15 5 3 9 8 10 13 12 14 20 18 25 6。能够得到如下二叉查找树:
最后检查一下控制台的输出: