二叉查找树是二叉树中最常用的一种类型,也叫二叉搜索树。顾名思义,二叉查找树是为了实现快速查找而生的。不过,它不仅仅支持快速查找一个数据,还支持快速插入、删除一个数据。它是怎么做到这些的呢?这些都依赖于二叉查找树的特殊结构。二叉查找树要求,在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值。
代码:
class Node {
constructor(num = 0){
this.value = num;
this.left = null;
this.right = null;
}
}
class SearchTree{
constructor(){
this.root = null;
}
print(){
let point = this.root;
if (point){
printAll(this.root.left);
console.log(this.root.value);
printAll(this.root.right);
}
function printAll(p){
if (p === null){
return;
}
printAll(p.left);
console.log(p.value);
printAll(p.right);
}
}
insert(num){
let node = new Node(num);
let p = this.getPrev(num);
if (!p){
this.root = node;
} else if(num < p.value){
p.left = node;
} else {
p.right = node;
}
}
getPrev(num, find = false) {
let point = this.root;
let res = [];
while (true) {
if (point && point.left && num < point.value) {
point = point.left;
continue
}
if (point && point.right && num >= point.value) {
if (find && num === point.value) {
res.push(point.value);
}
point = point.right;
continue
}
//如果是搜索
if (find) {
if (point.value === num) {
res.push(point.value);
}
if (res.length === 0) {
return null
}
if (res.length === 1) {
return res[0];
}
return res;
}
return point;
}
}
find(num) {
if (this.root === null) {
return
}
return this.getPrev(num, true);
}
remove(num) {
let point = this.root;
let prent = null;
let tree = this;
let res = null;
while (true) {
if (point.left) {
if (num < point.left.value || num < point.value) {
prent = point;
point = point.left;
continue
}
}
if (point.right) {
if (num >= point.right.value || num >= point.value) {
if (num === point.value) {
delMethod(point, prent);
if (prent === null) {
point = this.root;
} else {
prent = prent;
point = prent.right;
}
res = true;
continue
}
prent = point;
point = point.right;
continue
}
}
if (point.value === num) {
res = true;
delMethod(point, prent);
}
break;
}
return res;
function delMethod(delNode, parent) {
let p = delNode; // p指向要删除的节点
let pp = parent; // pp记录的是p的父节点
// 要删除的节点有两个子节点
if (p.left != null && p.right != null) { // 查找右子树中最小节点
let minP = p.right;
let minPP = p; // minPP表示minP的父节点
while (minP.left != null) {
minPP = minP;
minP = minP.left;
}
p.value = minP.value; // 将minP的数据替换到p中
p = minP; // 下面就变成了删除minP了
pp = minPP;
}
// 删除节点是叶子节点或者仅有一个子节点
let child; // p的子节点
if (p.left != null) child = p.left;
else if (p.right != null) child = p.right;
else child = null;
if (pp == null) {
tree.root = child
}
else if (pp.left == p) {
pp.left = child;
}
else {
pp.right = child;
}
}
}
}
python代码:
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
class BinarySearchTree:
def __init__(self):
self.root = None
def buildTree(self, data):
for d in data:
self.root = self.insert(self.root, d)
def insert(self, root, key):
if not root:
return Node(key)
if root.key < key:
root.right = self.insert(root.right, key)
elif root.key > key:
root.left = self.insert(root.left, key)
return root
def print(self, root):
if not root:
return
if root.left:
self.print(root.left)
print('=======:', root.key)
if root.right:
self.print(root.right)
def find(self, root, key):
if not root:
return None
if root.key == key:
return root
if root.key < key:
return self.find(root.right, key)
elif root.key > key:
return self.find(root.left, key)
return None
def delete(self, root, key):
if not root:
return None
if root.key < key:
root.right = self.delete(root.right, key)
elif root.key > key:
root.left = self.delete(root.left, key)
else:
if not root.left:
return root.right
if not root.right:
return root.left
root.key = self.findMin(root).key
root.right = self.delete(root.right, root.key)
def findMin(self, root):
while root and root.left:
root = root.left
return root
data = [3,4,1,78,21]
creatTree = BinarySearchTree()
creatTree.buildTree(data)
creatTree.print(creatTree.root)
result = creatTree.find(creatTree.root, 4)
print('find=1=4=:', result.key)
creatTree.delete(creatTree.root, 4)
result = creatTree.find(creatTree.root, 4)
print('find=2=4=:', result)