<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>二叉搜索树</title>
</head>
<body>
<script>
//二叉搜索树
function BinarySearchTree(){
//属性
function Node(key,value){
this.key = key;
this.value = value;
this.right = null;
this.left = null;
}
this.root = null;
//方法
//查询节点方法
BinarySearchTree.prototype.insertNode = function (node,newNode) {
if(newNode.key < node.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);
}
}
}
//插入,给用户调用的方法
BinarySearchTree.prototype.insert = function (key,value) {
//根据key创建节点
var newNode = new Node(key,value);
if(this.root == null){
this.root = newNode;
}else {
this.insertNode(this.root,newNode);
}
}
//查询
BinarySearchTree.prototype.search = function (key) {
var node = this.root;
while (node != null){
if (node.key > key){
node = node.left;
}else if(node.key < key){
node = node.right;
}else {
return node.value;
}
return false;
}
}
BinarySearchTree.prototype.preOrderTranversalNode = function (node,handler) {
if(node == null){
}else {
handler(node.key);
this.preOrderTranversalNode(node.left,handler)
this.preOrderTranversalNode(node.right,handler);
}
}
//通过先序遍历方式遍历所有节点
BinarySearchTree.prototype.preOrderTraverse = function (handler) {
if(this.root == null) return;
this.preOrderTranversalNode(this.root,handler);
}
BinarySearchTree.prototype.inOrderTranversalNode = function (node,handler) {
if(node == null){
}else {
this.inOrderTranversalNode(node.left,handler)
handler(node.key);
this.inOrderTranversalNode(node.right,handler);
}
}
//通过中序遍历所有节点
BinarySearchTree.prototype.inOrderTraverse = function(handler){
if(this.root == null) return;
this.inOrderTranversalNode(this.root,handler);
}
BinarySearchTree.prototype.postOrderTranversalNode = function (node,handler) {
if(node == null){
}else {
this.postOrderTranversalNode(node.left,handler)
this.postOrderTranversalNode(node.right,handler);
handler(node.key);
}
}
//通过后序遍历方式遍历所有节点
BinarySearchTree.prototype.postOrderTraverse = function (handler) {
if(this.root == null) return;
this.postOrderTranversalNode(this.root,handler);
}
//返回树中最小的值/键
BinarySearchTree.prototype.min = function () {
var current = this.root;
while (current.left!=null){
current = current.left;
}
return current.key;
}
//返回树中最大的值/键
BinarySearchTree.prototype.max = function () {
var curent = this.root;
while(curent.right != null){
curent = curent.right;
}
return curent.key;
}
//从树中移除某个键
BinarySearchTree.prototype.remove = function (deleteKey) {
var currentNode = this.root;
var parentNode = this.root;
var isLeftNode = true;
if (currentNode.left == null && currentNode.right == null && currentNode.key == deleteKey){
this.root = null;
}
while(deleteKey != currentNode.key){
parentNode = currentNode;
if (deleteKey < currentNode.key){
currentNode = currentNode.left;
isLeftNode = true;
}else {
currentNode = currentNode.right;
isLeftNode = false;
}
}
if (currentNode.left == null && currentNode.right == null)
{
if(isLeftNode){
parentNode.left = null;
}else {
parentNode.right = null;
}
}else if (currentNode.left == null){
if (isLeftNode)
{
parentNode.left = currentNode.right;
}else {
parentNode.right = currentNode.right;
}
}else if(currentNode.right == null){
if (isLeftNode){
parentNode.left = currentNode.left;
}else {
parentNode.right = currentNode.left;
}
}else {
//双节点删除,处理起来有点麻烦,需要获取一个和要删除节点最接近的数字,替换当前节点
//可以获取左节点最大值,或者获取右节点最小值
var findNode = this.getDeleteNodeLeftMaxNode(currentNode);
findNode.right = currentNode.right;
if (isLeftNode){
parentNode.left = findNode;
}else {
parentNode.right = findNode;
}
}
}
BinarySearchTree.prototype.getDeleteNodeLeftMaxNode = function (deleteNode) {
//获取到左侧最大节点时,他可能还有左节点需要将最大节点左节点赋给最大节点父节点对应位置
var parentNode = deleteNode;
var findNode = deleteNode.left;
while (findNode.right != null){
parentNode = findNode;
findNode = findNode.right
}
if (findNode.left != null)
{
parentNode.right = findNode.left
findNode.left = deleteNode.left
}
return findNode;
}
BinarySearchTree.prototype.getDeleteNodeRightMinNode = function (deleteNode) {
var parentNode = deleteNode;
var findNode = deleteNode.left;
while(findNode.left != null){
parentNode = findNode;
findNode = findNode.left;
}
if (findNode.right != null){
parentNode.left = findNode.right;
findNode.right = deleteNode.right;
}
return findNode;
}
}
//测试代码
var bst = new BinarySearchTree();
bst.insert(11,'hhsa')
bst.insert(7,'aha')
bst.insert(15,'awe')
bst.insert(5,'ahd')
bst.insert(3,'ate')
bst.insert(9,'aadg')
bst.insert(8,'aad')
bst.insert(10,'ag')
bst.insert(13,'ah')
bst.insert(12,'ae')
bst.insert(14,'at')
bst.insert(20,'ae')
bst.insert(18,'az')
bst.insert(25,'aa')
bst.remove(13);
// console.log(bst)
// var resultString = '';
// bst.preOrderTraverse(function (key) {
// resultString += key + ' '
// })
// alert(resultString)
//
// resultString = '';
// bst.inOrderTraverse(function (key) {
// resultString += key + ' '
// })
// alert(resultString)
// resultString = '';
// bst.postOrderTraverse(function (key) {
// resultString += key + ' '
// })
// alert(resultString)
// alert(bst.min());
// alert(bst.max());
alert(bst.search(30));
</script>
</body>
</html>