-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathBST.cpp
More file actions
236 lines (225 loc) · 4.52 KB
/
BST.cpp
File metadata and controls
236 lines (225 loc) · 4.52 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
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
class BSTNode{
public:
int val;
BSTNode* parent;
BSTNode* left;
BSTNode* right;
BSTNode() :val(), parent(nullptr), left(nullptr), right(nullptr){}
BSTNode(int v) :val(v), parent(nullptr), left(nullptr), right(nullptr){}
};
//输出一棵二叉搜索树
void InorderTreeWalk(BSTNode* x){
if (x != nullptr){
InorderTreeWalk(x->left);
cout << x->val << " ";
InorderTreeWalk(x->right);
}
return;
}
//中序遍历的非递归实现
void InorderUseStack(BSTNode* root){
stack<BSTNode*> s;
BSTNode *node = root;
while (node != nullptr || !s.empty()){
if (node != nullptr){
s.push(node);
node = node->left;
}
else{
node = s.top();
s.pop();
cout << node->val << " ";
node = node->right;
}
}
}
//不使用辅助栈的中序遍历
void InorderMorris(BSTNode* root){
BSTNode *cur = root, *pre = nullptr;
while (cur != nullptr){
//当前节点的左子树不存在
if (cur->left == nullptr){
cout << cur->val << " ";
//把当前节点换成右子树
cur = cur->right;
}
else{
pre = cur->left;
//找到前驱节点
while (pre->right != nullptr && pre->right != cur){
pre = pre->right;
}
//前驱节点没有处理过
if (pre->right == nullptr){
//处理前驱节点
pre->right = cur;
//左子树
cur = cur->left;
}
else{
//还原回去
pre->right = nullptr;
cout << cur->val << " ";
//把当前节点换成右子树
cur = cur->right;
}
}
}
}
//查找关键值为k的节点
BSTNode* TreeSearch(BSTNode* x, int k){
if (x == nullptr || x->val == k)//x就是要找的节点,或者树为空
return x;
if (k < x->val)//在左子树中
return TreeSearch(x->left, k);
else//在右子树中
return TreeSearch(x->right, k);
}
//得到最小节点
BSTNode* GetMin(BSTNode* x){
//迭代到最左侧节点
while (x->left != nullptr)
x = x->left;
return x;
}
//找到最大节点
BSTNode* GetMax(BSTNode* x){
//找到最右侧节点
while (x != nullptr)
x = x->right;
return x;
}
//得到后继节点
BSTNode* GetSuccessor(BSTNode* x){
//右子树中的最小节点
if (x->right != nullptr){
return GetMin(x->right);
}
//后继就是x的最底层祖先
BSTNode* y = x->parent;
while (y != nullptr && x == y->right){
x = y;
y = y->parent;
}
return y;
}
//插入节点
void Insert(BSTNode* T, BSTNode* z){
BSTNode* y = nullptr;
BSTNode* x = T;
//找到需要插入的位置
while (x != nullptr){
y = x;
if (z->val < x->val)
x = x->left;
else
x = x->right;
}
//把z接到树上
z->parent = y;
//T是空树
if (y == nullptr)
T = z;
//确定z应该是哪个子节点
else if (z->val < y->val)
y->left = z;
else
y->right = z;
}
//用节点v去替换u
void Transplant(BSTNode* T, BSTNode* u, BSTNode* v){
if (u->parent == nullptr)
T = v;
//确定u在父亲节点的哪个子树上
else if (u == u->parent->left)
u->parent->left = v;
else
u->parent->right = v;
//把v接到父亲节点上
if (v != nullptr)
v->parent = u->parent;
}
//删除节点z
void Delete(BSTNode* T, BSTNode* z){
//左子树不存在,用右子节点替代他
if (z->left == nullptr)
Transplant(T, z, z->right);
//右子树存在,左子树不存在,用左子节点替代他
else if (z->right == nullptr)
Transplant(T, z, z->left);
//两个节点都存在
else{
//y是z的后继节点
BSTNode* y = GetMin(z->right);
//y不是z的孩子
if (y->parent != z){
//用y的右孩子替换y
Transplant(T, y, y->right);
//把z的右孩子接到y上
y->right = z->right;
y->right->parent = y;
}
//用后继节点y替代z
Transplant(T, z, y);
//把z的左子树放到y的左边
y->left = z->left;
y->left->parent = y;
}
}
int main(){
vector<int> num = { 9, 5, 8, 6, 4, 3, 2, 7, 1, 10 };
BSTNode* root = new BSTNode();
for (int i = 0; i < num.size(); i++){
cout << "插入值为" << num[i] << "的节点" << endl;
if (i == 0)
root->val = num[i];
else{
BSTNode* in = new BSTNode(num[i]);
Insert(root, in);
}
}
cout << "构造的二叉搜索树为:";
InorderTreeWalk(root);
//InorderUseStack(root);
//InorderMorris(root);
cout << endl;
int input = 0;
while (1){
cout << "输入一个你需要插入节点的值,没有的话输入-1:";
cin >> input;
if (input == -1)
break;
else{
BSTNode* in = new BSTNode(input);
Insert(root, in);
}
}
cout << "新的二叉搜索树为:";
InorderTreeWalk(root);
//InorderUseStack(root);
//InorderMorris(root);
cout << endl;
while (1){
cout << "输入一个你需要删除节点的值,没有的话输入-1:";
cin >> input;
if (input == -1)
break;
else{
BSTNode* target = TreeSearch(root, input);
if (target == nullptr)
cout << "节点不存在" << endl;
else
Delete(root, target);
}
}
cout << "新的二叉搜索树为:";
InorderTreeWalk(root);
//InorderUseStack(root);
//InorderMorris(root);
cout << endl;
system("pause");
}