This repository was archived by the owner on Feb 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBT.cpp
More file actions
306 lines (262 loc) · 8.31 KB
/
BT.cpp
File metadata and controls
306 lines (262 loc) · 8.31 KB
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
#include <cstdlib>
#include "BT.h"
using namespace std;
BTree BT::NewTree(BTNode *parentNode, int m)
{
BTree node = (BTree)malloc(sizeof(BTNode));
node->parent = parentNode;
node->key = (KeyType *)calloc(m + 1, sizeof(KeyType));
node->key[0] = 0;
node->children = (BTree *)calloc(m + 1, sizeof(BTree));
return node;
}
bool BT::Search(BTree t, KeyType key)
{
BTree p;
return BT::__Search(t, key, p);
}
bool BT::Insert(BTree &t, KeyType key, int m)
{
BTree pos;
if (BT::isEmpty(t))
{
__Insert_Ordered(t, key);
return true;
}
else if (BT::__Search(t, key, pos))
return false;
else
{
BT::__Insert(pos, key, m, t);
return true;
}
}
bool BT::Delete(BTree &t, KeyType key, int m) // 删除结点,先查找,若不存在则返回false,否则删除并返回true
{
BTNode *p;
if (BT::__Search(t, key, p))
{
if (p->children[0])
BT::__Delete_NotTerminal(p, key, m, t);
else
BT::__Delete_Terminal(p, key, m, t);
return true;
}
else
return false;
}
void BT::Traverse(BTree t, void Visit(KeyType)) // 升序遍历(递归)
{
if (t)
{
BT::Traverse(t->children[0], Visit);
for (int i = 1; i <= t->key[0]; i++)
{
Visit(t->key[i]);
BT::Traverse(t->children[i], Visit);
}
}
}
bool BT::isEmpty(BTree t)
{
return !t->key[0];
}
void BT::__Insert(BTree &node, KeyType key, int m, BTree &root) // 综合插入,指定需插入结点,提供阶数m,提供root
{
BT::__Insert_Simple(node, key); // 先简单插入
while (node->key[0] == m && node->parent != NULL) // 需分裂且不为根结点
{
BT::__Split(node);
node = node->parent;
}
if (node->key[0] == m && node->parent == NULL) // 分裂根结点
BT::__Split_Root(root);
}
int BT::__Insert_Simple(BTNode *node, KeyType key) // 简单插入,输入不保证有序,结果可能需分裂,由调用者自行判断,返回值为插入位置
{
node->key[0]++;
// 按顺序插入
int i;
for (i = 1; node->key[i] < key && i < node->key[0]; i++) // 找到不小于key的最大值
;
for (int j = node->key[0]; j > i; j--)
node->key[j] = node->key[j - 1];
node->key[i] = key;
return i;
}
void BT::__Insert_Ordered(BTNode *node, KeyType key) // 顺序插入,仅在确保输入有序时使用
{
node->key[0]++;
node->key[node->key[0]] = key;
}
bool BT::__Split(BTNode *node) // 分裂,仅在非根结点分裂时使用
{
int m = node->key[0];
BTree parent = node->parent;
// 新结点处理
BTree newNode = BT::NewTree(parent, m); // 新结点
for (int i = (m + 3) / 2; i <= m; i++) // 插入所有关键字
BT::__Insert_Ordered(newNode, node->key[i]);
for (int i = (m + 1) / 2; i <= m; i++) // 插入所有子树并修改其parent
{
newNode->children[i - (m + 1) / 2] = node->children[i];
if (newNode->children[i - (m + 1) / 2])
newNode->children[i - (m + 1) / 2]->parent = newNode;
}
// 父结点处理
int pos = BT::__Insert_Simple(parent, node->key[(m + 1) / 2]); // 中间关键字上插进父结点
// 新结点插入父结点子树正确位置
for (int i = parent->key[0]; i > pos; i--)
parent->children[i] = parent->children[i - 1];
parent->children[pos] = newNode;
parent->children[pos - 1] = node; // 原结点位置
// 原结点处理
node->key[0] = (m - 1) / 2; // 修改n
for (int i = (m + 1) / 2; i <= m; i++) // children无效子树置为NULL
node->children[i] = NULL;
if (parent->key[0] == m) // 父结点满判断
return false;
else
return true;
}
void BT::__Split_Root(BTree &root) // 根分裂,修改指针
{
root->parent = BT::NewTree(NULL, root->key[0]);
BT::__Split(root);
root = root->parent;
}
bool BT::__Search(BTree t, KeyType key, BTree &pos) // 内部用搜索,找到返回所在结点,找不到返回要插入的结点指针
{
BTree node = t;
while (true)
{
int i = 1;
for (i = 1; node->key[i] < key && i < node->key[0]; i++) // 找到不小于key的最大值
;
if (node->key[i] == key)
{
pos = node;
return true;
}
else if (node->key[i] < key)
i++;
if (node->children[i - 1] == NULL)
{
pos = node;
return false;
}
node = node->children[i - 1];
}
}
void BT::__Delete_Simple(BTNode *node, KeyType key) // 简单删除,提供目标节点及目标key,删后不做任何处理
{
int pos = 1;
for (pos; node->key[pos] != key; pos++)
;
for (int i = pos + 1; i <= node->key[0]; i++)
{
node->key[i - 1] = node->key[i];
node->children[i - 1] = node->children[i];
}
node->key[0]--;
}
void BT::__Delete_NotTerminal(BTNode *node, KeyType key, int m, BTree &t) // 非终端结点删除
{
int pos = 1;
for (pos; node->key[pos] != key; pos++)
;
BTNode *next = node->children[pos];
for (next; next->children[0]; next = next->children[0])
;
node->key[pos] = next->key[1];
BT::__Delete_Terminal(next, next->key[1], m, t);
}
void BT::__Delete_Terminal(BTNode *node, KeyType key, int m, BTree &t) // 终端结点删除
{
if (node->key[0] >= (m + 1) / 2)
BT::__Delete_Simple(node, key);
else if (node->key[0] == (m + 1) / 2 - 1)
{
BTNode *parent = node->parent;
if (!parent)
{
BT::__Delete_Root(t, key);
return;
}
int posToDelete = 1;
for (posToDelete; node->key[posToDelete] != key; posToDelete++)
;
int posInParent = 0;
for (posInParent; parent->children[posInParent] != node; posInParent++)
;
BTNode *lb = parent->children[posInParent - 1],
*rb = parent->children[posInParent + 1];
if (posInParent < parent->key[0] && rb->key[0] > (m + 1) / 2 - 1) // 右brother to parent
{
node->key[posToDelete] = parent->key[posInParent + 1];
parent->key[posInParent + 1] = rb->key[1];
BT::__Delete_Simple(rb, rb->key[1]);
}
else if (posInParent > 0 && lb->key[0] > (m + 1) / 2 - 1) // 左brother to parent
{
node->key[posToDelete] = parent->key[posInParent];
parent->key[posInParent] = lb->key[lb->key[0]];
BT::__Delete_Simple(lb, lb->key[lb->key[0]]);
}
else if (posInParent > 0) // parent to 左
{
BT::__Delete_Simple(node, key);
int toAdd = node->key[0] + 1;
lb->key[lb->key[0] + 1] = parent->key[posInParent];
for (toAdd; toAdd > 1; toAdd--)
{
lb->key[lb->key[0] + toAdd] = node->key[toAdd - 1];
lb->children[lb->key[0] + toAdd] = node->children[toAdd - 1];
if (node->children[toAdd - 1])
node->children[toAdd - 1]->parent = lb;
}
lb->children[lb->key[0] + 1] = node->children[0];
lb->key[0] += toAdd;
free(node);
parent->children[posInParent] = NULL;
BT::__Delete_Terminal(parent, parent->key[posInParent], m, t);
}
else // parent to 右
{
BT::__Delete_Simple(node, key);
int toAdd = node->key[0] + 1;
for (int i = rb->key[0] + toAdd; i >= toAdd + 1; i--)
{
rb->key[i] = rb->key[i - toAdd];
rb->children[i] = rb->children[i - toAdd];
}
rb->children[toAdd] = rb->children[0];
rb->key[0] += toAdd;
rb->key[toAdd] = parent->key[posInParent + 1];
for (toAdd; toAdd > 1; toAdd--)
{
rb->key[toAdd - 1] = node->key[toAdd - 1];
rb->children[toAdd - 1] = node->children[toAdd - 1];
if (node->children[toAdd - 1])
node->children[toAdd - 1]->parent = rb;
}
rb->children[0] = node->children[0];
free(node);
parent->children[posInParent + 1] = NULL;
parent->children[posInParent] = rb;
BT::__Delete_Terminal(parent, parent->key[posInParent + 1], m, t);
}
}
}
void BT::__Delete_Root(BTree &t, KeyType key) // 根结点删除
{
if (t->key[0] > 1)
BT::__Delete_Simple(t, key);
else if (t->children[0])
t = t->children[0];
else if (t->children[1])
t = t->children[1];
else
t->key[0]--;
t->parent = NULL;
}