二叉搜索树

二叉搜索树

二叉树中的节点最多只能有两个子节点:一个是左侧子节点,另一个是右侧子节点。而二叉搜索树(BST)是二叉树的一种,但是只允许你在左侧节点存储(比父节点)小的值,在右侧节点存储(比父节点)大的值。

BinarySearchTree类的模拟实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// 创建节点Node类
class Node {
constructor(key) {
this.key = key;
this.left = null;
this.right = null;
}
}
const Compare = {
LESS_THAN: -1,
BIGGER_THAN: 1
};
function defaultCompare(a, b) {
if (a === b) {
return 0
}
return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN;
}
class BinarySearchTree {
// 构造函数
constructor(compareFn = defaultCompare) {
this.compareFn = compareFn;
this.root = null;
}
// 向二叉搜索树中插入一个值 - 辅助方法
insertNode(node, key) {
if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
if (node.left == null) {
node.left = new Node(key);
} else {
this.insertNode(node.left, key);
}
} else {
if (node.right == null) {
node.right = new Node(key);
} else {
this.insertNode(node.right, key);
}
}
}
// 向二叉搜索树中插入一个值
insert(key) {
if (this.root == null) {
this.root = new Node(key);
} else {
this.insertNode(this.root, key);
}
}
// 中序遍历 - 辅助方法
inOrderTraverseNode(node, callback) {
if (node != null) {
this.inOrderTraverseNode(node.left, callback);
callback(node.key);
this.inOrderTraverseNode(node.right, callback);
}
}
// 中序遍历
inOrderTraverse(callback) {
this.inOrderTraverseNode(this.root, callback);
}
// 先序遍历 - 辅助方法
preOrderTraverseNode(node, callback) {
if (node != null) {
callback(node.key);
this.preOrderTraverseNode(node.left, callback);
this.preOrderTraverseNode(node.right, callback);
}
}
// 先序遍历
preOrderTraverse(callback) {
this.preOrderTraverseNode(this.root, callback);
}
// 后序遍历 - 辅助方法
postOrderTraverseNode(node, callback) {
if (node != null) {
this.postOrderTraverseNode(node.left, callback);
this.postOrderTraverseNode(node.right, callback);
callback(node.key);
}
}
// 后序遍历
postOrderTraverse(callback) {
this.postOrderTraverseNode(this.root, callback);
}
// 搜索最小值 - 辅助方法
minNode(node) {
let current = node;
while (current != null && current.left != null) {
current = current.left;
}
return current;
}
// 搜索最小值
min() {
return this.minNode(this.root);
}
// 搜索最大值 - 辅助方法
maxNode(node) {
let current = node;
while (current != null && current.right != null) {
current = current.right;
}
return current;
}
// 搜索最大值
max() {
return this.maxNode(this.root);
}
// 搜索特定的值 - 辅助方法
searchNode(node, key) {
if (node == null) {
return false;
}
if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
return this.searchNode(node.left, key);
} else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
return this.searchNode(node.right, key);
} else {
return true;
}
}
// 搜索特定的值
search(key) {
return this.searchNode(this.root, key);
}
// 移除一个节点 - 辅助方法
removeNode(node, key) {
if (node == null) {
return null;
}
if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
node.left = this.removeNode(node.left, key);
return node;
} else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
node.right = this.removeNode(node.right, key);
return node;
} else {
// 第一种情况:移除一个叶节点
if(node.left == null && node.right == null) {
node = null;
return node;
}
// 第二种情况:移除有一个左侧或右侧子节点的节点
if (node.left == null) {
node = node.right;
return node;
} else if (node.right == null) {
node = node.left;
return node;
}
// 第三种情况:移除有两个子节点的节点
const aux = this.minNode(node.right);
node.key = aux.key;
node.right = this.removeNode(node.right, aux.key);
return node;
}
}
// 移除一个节点
remove(key) {
this.root = this.removeNode(this.root, key);
}
}

这里就不再演示BinarySearchTree类中方法的使用了,有兴趣的可以自己做个demo测试一下,如果有任何的问题,欢迎评论区留言。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2020-2021 Sanmu
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信