完整实现一个二叉搜索树(BST)
1. 二叉搜索树(BST)介绍:
二叉树就是最多有两个子节点,一个是左侧子节点,一个是右侧子节点。这个定义有助于我们写出更高效地在树中插入,查找和删除节点的算法。
二叉搜索树(BST)是二叉树的一种,但是只允许你在左侧节点存储(比父节点)小的值,在右侧节点存储(比父节点)大的值。
2. 二叉搜索树所具备的一些功能
insert(key): 向树中插入一个新的键
search(key): 在树中查找一个键,如果节点存在,则返回节点;如果不存在则返回false。
insert(key): 向树中插入一个新的键
search(key): 在树中查找一个键,如果节点存在,则返回节点;如果不存在则返回false。
inOrderTraverse(); 中序遍历所有节点(左根右)
preOrderTraverse(); 先序遍历所有节点(根左右)
postOrderTraverse(); 后序遍历所有节点(左右根)
min(); 返回树中最小的值/键
max(); 返回树中最大的值/键
remove(); 从树中移除某个键
3.下面是二叉树完整实现代码:
class Node { // 创建节点
constructor(data) {
this.root = this;
this.data = data;
this.left = null;
this.right = null;
}
}
class BinarySearchTree {
constructor() {
this.root = null //初始化根节点
}
// 插入节点
insert(data) {
const newNode = new Node(data);
const insertNode = (node, newNode) => { //插入函数定义
if (newNode.data < node.data) { // 如果插入的节点值比父节点小则插入到左节点上反之则插入到右节点上
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)
}
}
}
if (!this.root) {
this.root = newNode;
} else {
insertNode(this.root, newNode);
}
}
// 中序遍历所有节点(左根右)
inOrderTraverse() {
let backs = [];
const callback = data => {
return data
}
const inOrderNode = (node, callback) => {
if (node !== null) {
inOrderNode(node.left, callback); // 递归遍历出左节点
backs.push(callback(node.data)); // 将值push到数组里
inOrderNode(node.right, callback) // 递归遍历出右节点
}
}
inOrderNode(this.root, callback)
return backs
}
// 先序遍历所有节点(根左右)
preOrderTraverse() {
let backs = [];
const callback = data => {
return data
}
const inOrderNode = (node, callback) => {
if (node !== null) {
backs.push(callback(node.data)); // 将值push到数组里
inOrderNode(node.left, callback); // 递归遍历出左节点
inOrderNode(node.right, callback) // 递归遍历出右节点
}
}
inOrderNode(this.root, callback)
return backs
}
// 后序遍历所有节点(左右根)
postOrderTraverse() {
let backs = [];
const callback = data => {
return data
}
const inOrderNode = (node, callback) => {
if (node !== null) {
inOrderNode(node.left, callback); // 递归遍历出左节点
inOrderNode(node.right, callback) // 递归遍历出右节点
backs.push(callback(node.data)); // 将值push到数组里
}
}
inOrderNode(this.root, callback)
return backs
}
//查找最小值
// 这里可以利用search 查找指定节点下面的最小值
min(node) {
const minNode = (node) => {
return node ? (node.left ? minNode(node.left) : node) : null
}
return minNode(node || this.root)
}
// 查找最大值
max(node) {
const maxNode = (node) => {
return node ? (node.right ? maxNode(node.right) : node) : null
}
return maxNode(node || this.root)
}
//查找特定值
search(data) {
const searchNode = (node) => {
if (node === null) return false;
if (node.data === data) {
return node;
}
return searchNode(data < node.data ? node.left : node.right, data)
}
return searchNode(this.root, data)
}
//从树中移除某个键
remove(data) { // 删除节点复杂之处在于每次删除节点时候二叉树要根据不同情况改变结构 同样也需要递归
const removeNode = (node, data) => {
if (node === null) return null;
if (node.data === data) {
if (node.left === null && node.right === null) return null;
if (node.left === null) return node.right;
if (node.right === null) return node.left;
if (node.left !== null && node.right !== null) {
let _node = this.min(node.right);
node.data = _node.data;
node.right = removeNode(node.right, _node.data);
return node
}
} else if (data < node.data) {
node.left = removeNode(node.left, data);
return node
} else {
node.right = removeNode(node.right, data);
return node
}
};
return removeNode(this.root, data)
}
}
const tree = new BinarySearchTree();
tree.insert(11);
tree.insert(7);
tree.insert(5);
tree.insert(3);
tree.insert(9);
tree.insert(8);
tree.insert(10);
tree.insert(13);
tree.insert(12);
tree.insert(14);
tree.insert(20);
tree.insert(18);
tree.insert(25);
console.log(tree.inOrderTraverse())
console.log(tree.preOrderTraverse())
console.log(tree.postOrderTraverse())
console.log(tree.min());
console.log(tree.max());
console.log(tree.search(20))
console.log(tree.remove(7))
4. 总结
二叉树也是js数据结构以及算法中比较重要的,因为其树的结构是严格按照左小右大的规律插入的,那么就可以通过递归的思想去实现一些基本功能。包括中序,先序,后序排序等都是通过递归的思想。