forked from CodePanda66/CSPostgraduate-408
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DS_4_3_ThreadedBiTree.cpp
243 lines (213 loc) · 6.33 KB
/
DS_4_3_ThreadedBiTree.cpp
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
//
// Created by Kim Yang on 2020/8/23.
// Copyright (c) Kim Yang All rights reserved.
//
#include <stdio.h>
//线索二叉树
/**定义模块**/
struct ElemType {
int value;
};
typedef struct ThreadNode {
ElemType data;//数据域
struct ThreadNode *lchild, *rchild;//左右孩子指针
int ltag, rtag;//左右线索标志
} ThreadNode, *ThreadTree;
/**定义模块**/
/**实现模块**/
ThreadNode *pre = NULL;//全局变量用于暂存当前访问结点的前驱
void visit(ThreadNode *q) {
if (q->lchild == NULL) {//左子树为空,建立前驱线索
q->lchild = pre;
q->ltag = 1;
}
if (pre != NULL && pre->rchild == NULL) {//建立前驱结点的后继线索
pre->rchild = q;
pre->rtag = 1;
}
pre = q;
}
//中序遍历二叉树,一边遍历一边线索化
void InThread(ThreadTree T) {
if (T != NULL) {
InThread(T->lchild);
visit(T);
InThread(T->rchild);
}
}
//创建中序线索化二叉树T
void CreatInThread(ThreadTree T) {
pre = NULL;
if (T != NULL) {//非空二叉树才能线索化
InThread(T);//中序线索二叉树
if (pre->rchild == NULL) {
pre->rtag = 1;//处理遍历的最后最后一个结点
}
}
}
//中序线索化(王道教材版)
void InThread_CSKaoYan(ThreadTree p, ThreadTree &pre) {
if (p != NULL) {
InThread_CSKaoYan(p->lchild, pre);//递归,线索化左子树
if (p->lchild == NULL) {//左子树为空,建立前驱线索
p->lchild = pre;
p->ltag = 1;
}
if (pre != NULL && pre->rchild == NULL) {
pre->rchild == p;//建立前驱结点的后及线索
pre->rtag = 1;
}
pre = p;
InThread_CSKaoYan(p->rchild, pre);
}
}
//中序线索化二叉树(王道教材版本)
void CreatInThread_CSKaoYan(ThreadTree T) {
ThreadTree pre = NULL;
if (T != NULL) {
InThread_CSKaoYan(T, pre);
pre->rchild = NULL;//思考:为什么处理最后一个结点时没有判断rchild 是否为NULL?
pre->rtag = 1;//答:因为最后一个结点的右孩子必为空。
}
}
//先序线索化,一边遍历一边线索化
void PreThread(ThreadTree T) {
if (T != NULL) {
visit(T);
if (0 == T->ltag) {//lchild不是前驱线索
PreThread(T->lchild);
}
PreThread(T->rchild);
}
}
//创建先序线索化二叉树T
void CreatPreThread(ThreadTree T) {
pre == NULL;
if (T != NULL) {
PreThread(T);
if (pre->rchild == NULL) {
pre->rtag = 1;//处理遍历的最后一个结点
}
}
}
//先序线索化(王道教程版本)
void PreThread_CSKaoYan(ThreadTree p, ThreadTree &pre) {
if (p != NULL) {
if (p->lchild == NULL) {
p->lchild = pre;
p->ltag = 1;
}
if (pre != NULL && pre->rchild == NULL) {
pre->rchild == p;//建立前驱结点的后及线索
pre->rtag = 1;
}
pre = p;
if (0 == p->ltag) {
PreThread_CSKaoYan(p->lchild, pre);
}
PreThread_CSKaoYan(p->rchild, pre);
}
}
//先序线索化二叉树(王道教材版本)
void CreatPreThread_CSKaoYan(ThreadTree T) {
ThreadTree pre = NULL;
if (T != NULL) {
PreThread_CSKaoYan(T, pre);
if (pre->rchild = NULL)//处理遍历的最后一个结点
pre->rtag = 1;
}
}
//后序线索二叉树
void PostThread(ThreadTree T) {
if (T != NULL) {
PostThread(T->lchild);
PostThread(T->rchild);
visit(T);
}
}
//创建后序线索二叉树T
void CreatPostThread(ThreadTree T) {
pre == NULL;
if (T != NULL) {
PostThread(T);
if (pre->rchild == NULL) {
pre->rtag = 1;//处理遍历的最后一个结点
}
}
}
//后序线索化(王道教程版本)
void PostThread_CSKaoYan(ThreadTree p, ThreadTree &pre) {
if (p != NULL) {
PostThread_CSKaoYan(p->lchild, pre);
PostThread_CSKaoYan(p->rchild, pre);
if (p->lchild == NULL) {
p->lchild = pre;
p->ltag = 1;
}
if (pre != NULL && pre->rchild == NULL) {
pre->rchild == p;//建立前驱结点的后及线索
pre->rtag = 1;
}
pre = p;
}
}
//后序线索化二叉树(王道教材版本)
void CreatPostThread_CSKaoYan(ThreadTree T) {
ThreadTree pre = NULL;
if (T != NULL) {
PostThread_CSKaoYan(T, pre);
if (pre->rchild = NULL)//处理遍历的最后一个结点
pre->rtag = 1;
}
}
//中序线索二叉树找中序后继
//找到以P为根的子树中,第一个被中序遍历的结点
ThreadNode *FirstNode(ThreadNode *p){
//循环找到最左下结点(不一定是叶结点)
while(0==p->ltag){
p=p->lchild;
}
return p;
}
//在中序线索二叉树中找到结点p的后继结点
ThreadNode *NextNode(ThreadNode *p){
//在右子树中最左下结点
if(0==p->rtag)return FirstNode(p->rchild);
else return p->rchild;
}
//对中序线索二叉树进行中序遍历(利用线索实现的非递归算法),空间复杂度为O(1);
void InOrder(ThreadNode *T){
for (ThreadNode *p = FirstNode(T); p!=NULL ; p=NextNode(p)) {
visit(p);
}
}
//中序线索二叉树找中序前驱
//找到以p为根的子树中,最后一个被中序遍历的结点
ThreadNode *LastNode(ThreadNode *p){
//循环找到最右下结点(不一定是叶结点)
while(0==p->rtag)p=p->rchild;
return p;
}
//在中序线索二叉树中找到结点p的前驱结点
ThreadNode *PreNode(ThreadNode *p){
//左下子树中最右结点
if(0==p->ltag)return LastNode(p->lchild);
else return p->lchild;
}
//对中序线索二叉树进行逆向中序遍历
void RevInOrder(ThreadNode *T){
for (ThreadNode *p = LastNode(T); p!=NULL ; p=PreNode(p)) {
visit(p);
}
}
/**实现模块**/
/**测试模块**/
void testModule() {
printf("开始测试!\n");
printf("结束测试!\n");
}
/**测试模块**/
int main() {
testModule();
return 0;
}