JavaScript数据结构——二叉搜索树
JavaScript数据结构(二叉搜索树)
二叉搜索树
二叉搜索树是一棵二叉树,可以为空。
如果不为空,则满足以下性质:
- 条件 1:非空左子树的所有键值小于其根节点的键值;
- 条件 2:非空右子树的所有键值大于其根节点的键值;
- 条件 3:左、右子树本身也都是二叉搜索树;
二叉搜索树的封装
二叉搜索树的常见操作
insert(key)
向树中插入一个新的键。search(key)
在树中查找一个键,如果节点存在,则返回 true;如果不存在,则返回false
。preOrderTraverse
通过先序遍历方式遍历所有节点。inOrderTraverse
通过中序遍历方式遍历所有节点。postOrderTraverse
通过后序遍历方式遍历所有节点。min
返回树中最小的值/键。max
返回树中最大的值/键。remove(key)
从树中移除某个键。
Node节点类
class Node {
constructor(key, value) {
this.key = key;
this.value = value;
this.left = null;
this.right = null;
}
}
二叉搜索树封装类
class SearchTree {
constructor() {
this.root = null;
}
// 插入代码
insert(key, value) {
const node = new Node(key, value);
// 插入分为两种情况,当根节点为空时;
if (this.root == null) {
this.root = node;
} else {
this.insertSearch(this.root, node)
}
}
insertSearch(oldNode, node) {
if (oldNode.key > node.key) {
if (oldNode.left == null) {
oldNode.left = node;
} else {
this.insertSearch(oldNode.left, node);
}
} else if (oldNode.key < node.key) {
if (oldNode.right == null) {
oldNode.right = node;
} else {
this.insertSearch(oldNode.right, node);
}
} else {
return false;
}
}
//遍历代码
PreOrder() {
if (this.root == null) {
return;
} else {
this.PreOrderNode(this.root)
}
}
PreOrderNode(node) {
if (node != null) {
console.log(node.key);
this.PreOrderNode(node.left);
this.PreOrderNode(node.right);
}
}
//中序遍历
InOrder() {
if (this.root == null) {
return
} else {
this.InOrderNode(this.root)
}
}
InOrderNode(node) {
if (node != null) {
this.InOrderNode(node.left);
console.log(node.key);
this.InOrderNode(node.right);
}
}
// 后序遍历
PostOrder() {
if (this.root == null) {
return
} else {
this.PostOrderNode(this.root);
}
}
PostOrderNode(node) {
if (node != null) {
this.PostOrderNode(node.left);
this.PostOrderNode(node.right);
console.log(node.key);
}
}
//`min`z最小值
min() {
if (!this.root) return
let node = this.root;
while (node.left != null) {
node = node.left;
}
return node;
}
//`max`z最小值
max() {
if (!this.root) return
let node = this.root;
while (node.right != null) {
node = node.right;
}
return node;
}
remove(key) {
if (this.root == null) {
return;
} else {
let currentNode = this.root;
let prevNode = currentNode;
while (currentNode && (currentNode.left || currentNode.right)) {
if (currentNode.key > key) {
prevNode = currentNode;
currentNode = currentNode.left;
} else if (currentNode.key < key) {
prevNode = currentNode;
currentNode = currentNode.right;
} else {
break;
}
}
// 如果找到的是叶节点
if (!currentNode.left && !currentNode.right) { // 页节点
if (prevNode.left == currentNode) prevNode.left = null;
if (prevNode.right == currentNode) prevNode.right = null;
return
} else if (!currentNode.left || !currentNode.right) { //只有一个子节点的节点
if (prevNode.left == currentNode) {
if (currentNode.left) {
prevNode.left = currentNode.left;
} else {
prevNode.left = currentNode.right;
}
} else {
if (currentNode.right) {
prevNode.right = currentNode.right;
} else {
prevNode.right = currentNode.left;
}
}
return
} else {
console.log(prevNode);
console.log(currentNode);
let successNode = currentNode.right;
let headNode = successNode;
while (successNode && successNode.left) {
headNode = successNode;
successNode = successNode.left;
}
// 后继节点的父节点 headNode
// successNode 后继节点
if (headNode == successNode) {
if (successNode.right) {
currentNode.right = successNode.right;
if (prevNode.left == currentNode) {
prevNode.left = successNode;
}
if (prevNode.right == currentNode) {
prevNode.right = successNode;
}
successNode.left = currentNode.left;
successNode.right = currentNode.right;
} else {
if (prevNode.left == currentNode) {
prevNode.left = successNode;
}
if (prevNode.right == currentNode) {
prevNode.right = successNode;
}
successNode.left = currentNode.left;
}
} else {
if (successNode.right) {
headNode.left = successNode.right;
if (prevNode.left == currentNode) {
prevNode.left = successNode;
}
if (prevNode.right == currentNode) {
prevNode.right = successNode;
}
successNode.left = currentNode.left;
successNode.right = currentNode.right;
} else {
headNode.left = null
if (prevNode.left == currentNode) {
prevNode.left = successNode;
}
if (prevNode.right == currentNode) {
prevNode.right = successNode;
}
successNode.left = currentNode.left;
successNode.right = currentNode.right;
}
}
if (currentNode == this.root) {
this.root = successNode
}
}
}
}
}
代码测试
console.log(searchTree);
//
//SearchTree {
// root: Node {
// key: 11,
// value: { name: '小付1' },
// left: Node { key: 7, value: [Object], left: [Node], right: [Node] },
// right: Node { key: 15, value: [Object], left: [Node], right: [Node] }
// }
//}
searchTree.PreOrder();
// 11 7 5 3 9 8 15 13 12 14 20 18 19 25
searchTree.InOrder();
// 3 5 7 8 9 10 11 12 13 14 15 18 19 20 25
searchTree.PostOrder()
//3 5 8 10 9 7 12 14 13 19 18 25 20 15 11
console.log(searchTree.min());
// Node { key: 3, value: { name: '小付6' }, left: null, right: null }
console.log(searchTree.max());
// Node { key: 25, value: { name: '小付14' }, left: null, right: null }
searchTree.remove(10);
searchTree.PreOrder();
//11 7 5 3 9 8 15 13 12 14 20 18 19 25