版权声明:Oreo https://blog.csdn.net/weixin_43154931/article/details/82822704
JavaScript实现二叉搜索树(BST)
- 二叉搜索树定义
- 二叉搜索树JavaScript代码实现
1. 二叉搜索树
二叉查找树(英语:Binary Search Tree),也称为二叉搜索树、有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
- 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
- 任意节点的左、右子树也分别为二叉查找树;
- 没有键值相等的节点。
–(wiki百科)
2. 二叉搜索树代码实现
const BinarySearchTree = function() {
let Node = function(key) {
this.key = key;
this.left = null;
this.rigth = null;
};
let root = null;
this.insert = function(key) {
// 向树中插入一个新的键
let newNode = new Node(key);
if (root === null) {
root = new Node(key);
} else {
insertNode(root, newNode);
};
const insertNode = function(node, newNode) {
if (newNode.key < node.key) {
if (node.left === null) {
node.left = newNode;
} else {
// 递归
insertNode(node.left, newNode);
}
} else {
if (node.rigth === null) {
node.rigth = newNode;
} else {
insertNode(node.rigth, newNode);
}
}
};
};
const inOrderTraverseNode = function(node, callback) {
if (node !== null) {
inOrderTraverseNode(node.left, callback);
callback(node.key);
inOrderTraverseNode(node.rigth, callback);
}
};
this.inOrderTraverse = function(callback) {
// 通过中序遍历遍历所有节点, 即从小到大顺序访问节点
inOrderTraverseNode(root, callback);
};
const preOrderTraverseNode = function(node, callback) {
if (node !== null) {
callback(node.key);
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.rigth, callback);
}
};
this.preOrderTraverse = function(callback) {
// 先序遍历,即优先于后代节点的顺序访问每个节点。
preOrderTraverseNode(root, callback)
};
const postOrderTraverseNode = function(node, callback) {
if (node !== null) {
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.rigth, callback);
callback(node.key);
}
};
this.postOrderTraverse = function(callback) {
// 后序遍历,即先访问节点的后代节点再访问节点本身。
postOrderTraverseNode(root, callback);
};
const minNode = function(node) {
if(node) {
while(node && node.left !== null) {
node = node.left;
}
return node.key;
}
return null;
};
this.min = function() {
// 搜索最小值
return minNode(root);
};
const maxNode = function(node) {
if(node) {
while(node && node.rigth !== null) {
node = node.right;
}
return node.key;
}
return null;
};
this.max = function() {
// 搜索最大值
return maxNode(root);
};
const searchNode = function(node, key) {
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 {
return true;
}
};
this.search = function(key) {
// 在树中查找一个键,如果节点存在,返回true,不存在,返回false
return searchNode(root, key);
};
const findMinNode = function(node) {
while (node && node.left !== null) {
node = node.left;
}
return node;
};
const 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 {
// key == node.key
if (node.left === null && node.right ===null) {
// 该节点是叶节点(没有子节点)
node = null;
return node;
} else if (node.left === null) {
// 该节点有一个右节点
node = node.rigth;
return node;
} else if (node.right === null) {
node = node.left;
return node;
} else {
// 有两个子节点
let aux = findMinNode(node.right);
node.key = aux.key;
node.right = removeNode(node.right, aux.key);
return node;
}
}
};
this.remove = function(key) {
// 移除某个键
root = removeNode(root, key);
};
}
二叉搜索树缺点:取决于添加的节点,树的一条边可能会非常深。为了解决这个问题可以使用Adelson-Velskii-landi树(AVL树)即自平衡二叉搜索树。