/
implementation.c
421 lines (346 loc) · 7.44 KB
/
implementation.c
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
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "definition.h"
SearchTree MakeEmpty (SearchTree T)//把一棵树清空
{
if(T!=null)
{
MakeEmpty(T->Left);//递归实现
MakeEmpty(T->Right);
free(T);
}
}
/*Position Find(int X,SearchTree T)//查找元素X的位置
{
if(T==null)
{
return null;
}
else if(X<T->Element)
return Find(X,T->Left);
else if(X>T->Element)
return Find(X,T->Right);
else
return T;
} */
int FindMid(int X,SearchTree T)//查找元素X的位置
{
int num=0;
if(T==null)
{
//printf("错误:二叉树为空");
return 0;
}
else
{
if(X<T->Element)
num = FindMid(X,T->Left);
else if(X>T->Element)
num = FindMid(X,T->Right)+FindMid(T->Element,T);
else
num=Num(T->Left)+1;
}
return num;
}
int FindPre(int X,SearchTree T)//查找元素X的先序遍历位置
{
int num=0;
if(T==null)
{
//printf("错误:二叉树为空");
return 0;
}
else
{
if(X<T->Element)
num = FindPre(X,T->Left)+1;
else if(X>T->Element)
num = FindPre(X,T->Right)+Num(T->Left)+1;
else
num=1;
}
return num;
}
Position FindMin(SearchTree T)//找到树中的最小值,并返回位置指针
{
if(T==null)
{
printf("错误:二叉树为空");
return null;
}
else if(T->Left==null)
return T;
else
return FindMin(T->Left);
}
Position FindMax(SearchTree T)//找到树中的最大值,并返回位置指针
{
if(T==null)
{
printf("错误:二叉树为空");
return null;
}
else if(T->Right==null)
return T;
else
return FindMax(T->Right);
}
SearchTree Insert(int X,SearchTree T)//插入
{
int i=0,j=0;
if(T==null)//当找到最后那个可以插入的叶子、或叶子的上一级即可完成插入
{
T=malloc(sizeof(struct TreeNode));
if(T==null)
printf("致命错误,内存溢出!!!");
else
{
T->Element=X;
T->Left=T->Right=null;
T->Height = 0;
}
}
else
if(X<T->Element)//递归实现
{
T->Left = Insert(X,T->Left);
if(Height(T->Left)-Height(T->Right)==2)
if(X<T->Left->Element)
T=SingleRotateLeft(T);
else
T=DoubleRotateLeft(T);
}
else if(X>T->Element)//递归实现
{
T->Right = Insert(X,T->Right);
// i=Height(T->Right);
// j=Height(T->Left);
if(Height(T->Right)-Height(T->Left)==2)
if(X>T->Right->Element)
T=SingleRotateRight(T);
else
T=DoubleRotateRight(T);
}
T->Height=Max(Height(T->Left),Height(T->Right))+1;
return T;
}
/*SearchTree Delete(int X,SearchTree T)//删除
{
Position Tem;
if(T==null)
printf("树中没有%d元素",X);
else if(X<T->Element)
{
T->Left = Delete(X,T->Left);
T->Height=Max(Height(T->Left),Height(T->Right))+1;
if(Height(T->Right)-Height(T->Left)==2)
if(T->Right->Right!=null)//此时要用右单螺旋
T=SingleRotateRight(T);
else
T=DoubleRotateRight(T);
}
else if(X>T->Element)
{
T->Right = Delete(X,T->Right);
if(Height(T->Left)-Height(T->Right)==2)
if(T->Left->Left!=null)
T=SingleRotateLeft(T);
else
T=DoubleRotateLeft(T);
}
else if(T->Left&&T->Right)//分两种情况:T有两子孩子,有一个或零个孩子
{
Tem = FindMin(T->Right);
T = Tem;
T->Right = Delete(Tem->Element,T->Right);
if(Height(T->Left)-Height(T->Right)==2)//判断删除元素后是否需要旋转进行重新排列
if(X<T->Left->Element)
T=SingleRotateLeft(T);
else
T=DoubleRotateLeft(T);
}
else //一个或零个孩子 ,这种情况不需要重新排列。
{
Tem = T;
if(T->Left==null)
T=T->Right;
else if(T->Right==null)
T=T->Left;
free(Tem);
}
if(T==null)
T->Height=-1;
else
T->Height=Max(Height(T->Left),Height(T->Right))+1;
return T;
}*/
SearchTree Delete(int X,SearchTree T)//删除后要调整高度,各种判断条件太麻烦了,所以删完遍历一遍,然后重新插入一遍就OK
{
SearchTree ReOrderTree;
Position Tem;
if(T==null)
printf("树中没有%d元素",X);
else if(X<T->Element)
{
T->Left = Delete(X,T->Left);
}
else if(X>T->Element)
{
T->Right = Delete(X,T->Right);
}
else if(T->Left&&T->Right)//分两种情况:T有两子孩子,有一个或零个孩子
{
Tem = FindMin(T->Right);
T = Tem;
T->Right = Delete(Tem->Element,T->Right);
}
else //一个或零个孩子 ,这种情况不需要重新排列。
{
Tem = T;
if(T->Left==null)
T=T->Right;
else if(T->Right==null)
T=T->Left;
free(Tem);
}
// T->Height=Max(Height(T->Left),Height(T->Right))+1;
Tree = null;
ReOrder(T);
ReOrderTree=Tree;
Tree = null;
return ReOrderTree;
}
int Height(Position P)//计算AVL节点的高度
{
if(P==null)
return -1;
else
return P->Height;
}
int Max(int T1,int T2)//得到最大深度
{
return (T1-T2>=0)?T1:T2;//三元选择
}
void PrintMid(SearchTree T)//中序打印出来
{
if(T==null)
{
printf("错误,链表为空!");
return ;
}
/*else
{
if(T->Left!=null)
PrintMid(T->Left);
printf(" %d ",T->Element );
if(T->Right!=null)
PrintMid(T->Right);
}*/
else if(T->Left!=null)
{
PrintMid(T->Left);
}
printf(" %d ",T->Element );
if(T->Right!=null)
PrintMid(T->Right);
}
void PrintPre(SearchTree T)//先序遍历打印出来
{
if(T==null)
printf("错误,链表为空!");
else
{
if(T->Left!=null)
PrintPre(T->Left);
if(T->Right!=null)
PrintPre(T->Right);
printf(" %d ",T->Element );
}
}
Position SingleRotateLeft(Position K2)//左单螺旋
{
Position K1;
K1=K2->Left;
K2->Left=K1->Right;
K1->Right=K2;
K2->Height=Max(Height(K2->Left),Height(K2->Right))+1;
K1->Height=Max(Height(K1->Left),Height(K1->Right))+1;
return K1;
}
Position SingleRotateRight(Position K2)//右单螺旋
{
Position K1;
K1=K2->Right;
K2->Right=K1->Left;
K1->Left=K2;
K2->Height=Max(Height(K2->Left),Height(K2->Right))+1;
K1->Height=Max(Height(K1->Left),Height(K1->Right))+1;
return K1;
}
Position DoubleRotateLeft(Position K3)//左双螺旋
{
K3->Left= SingleRotateRight(K3->Left);
return SingleRotateLeft(K3);
}
Position DoubleRotateRight(Position K3)//右双螺旋
{
K3->Left= SingleRotateLeft(K3->Right);
return SingleRotateLeft(K3);
}
void Print(SearchTree Tree)//打印出二叉树,中序+先序 唯一确定
{
printf("这个二叉树的中序遍历结果是:\n");
PrintMid(Tree);
printf("\n这个二叉树的先序遍历结果是:\n");
PrintPre(Tree);
printf("\n");
}
void ReOrder(SearchTree T)//对二叉树的重新排布
{
if(T==null)
{
return;
}
else
{
Tree = Insert(T->Element,Tree);//通过递归把被破坏的二叉树的元素重新插入到全局变量Tree
if(T->Left!=null)
ReOrder(T->Left);
if(T->Right!=null)
ReOrder(T->Right);
}
}
int Num(SearchTree T)//一个二叉树中有多少个元素
{
int sum=0;
// number=0;
if(T==null)
{
return 0;
}
/*else
{
if(T->Left!=null)
PrintMid(T->Left);
printf(" %d ",T->Element );
if(T->Right!=null)
PrintMid(T->Right);
}*/
else
{
if(T->Left!=null)
{
//number+=Num(T->Left);
sum+=Num(T->Left);
}
//number++;
sum++;
if(T->Right!=null)
//number+=Num(T->Right);
sum+=Num(T->Right);
}
//sum=number;
// number=0;
return sum;
}