代码如下:

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
#include<iostream>
#include<cstdio>
using namespace std;

#define OK 1
#define ERROR 0

typedef int Status;
typedef char TElemType;
/*
定义线索二叉树的数据结构
*/
typedef struct BiThrNode
{
char data;//结点对应的数据
int ltag, rtag;//左右孩子标记
struct BiThrNode *lchild;//左孩子
struct BiThrNode *rchild;//右孩子
}BiThrNode,*BiThrTree;
<!--more-->
/*
输出对应结点里面的值
*/
Status PrintElement(TElemType e)
{
cout << e;
return OK;
}


/*
寻找p结点在Thrt树中的父节点,便于进行后序遍历
*/
BiThrTree parent(BiThrTree &Thrt, BiThrTree &p)
{
BiThrTree temp=Thrt->lchild;

if (p==Thrt->lchild)//p即为根节点,返回创建的头结点
{
return Thrt;
}
if (temp->lchild == p)
{
return temp;//父节点就是我们寻找的结点
}
else
{
temp = temp->lchild;
while (temp->lchild != p&&temp->rchild != p)
{
/*
如果节点有右孩子,那就往右
如果节点没有右孩子,就往左
没有左孩子,就往前驱
*/
if (temp->rtag == 0)
{
temp = temp->rchild;
}
else
{
temp = temp->lchild;
}
}
return temp;
}
}



/*
创建线索二叉树,初始化跟二叉树的初始化递归算法一样
*/
Status CreateBiThrTree(BiThrTree &T)
{
char ch;
cin >> ch;
if (ch == '#')
T = NULL;
else
{
if (!(T = (BiThrNode *)malloc(sizeof(BiThrNode))))
exit(OVERFLOW);

T->data = ch;
T->ltag = 0;
T->rtag = 0;
CreateBiThrTree(T->lchild);
CreateBiThrTree(T->rchild);
}
return OK;
}

/*
T指向头结点,头结点的左链lchild指向根节点
中序遍历二叉线索树T的非递归算法,对每个数据元素调用函数Visit
*/
Status InOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e))
{
BiThrTree p = T->lchild;
while (p&&(p != T))
{
while (p->ltag == 0)
{
p = p->lchild;
}
Visit(p->data);
while (p->rtag == 1 && p->rchild != T)
{
p = p->rchild;
Visit(p->data);
}
p = p->rchild;
}
return OK;
}
/*
前序遍历二叉树非递归算法(仿造中序遍历)
*/
Status PreOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e))
{
BiThrTree p = T;
while (p)
{
while (p->ltag == 0)
{
Visit(p->data);
p = p->lchild;
}
Visit(p->data);
p = p->rchild;
}
return OK;
}
/*
后序遍历二叉树非递归算法
*/
Status PostOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType e))
{
BiThrTree p = T->lchild;
BiThrTree pre = T;

//p指向第一个被访问结点
while (p->ltag == 0||p->rtag==0)
{
while(p->ltag==0)
p = p->lchild;
if (p->rtag == 0)
p = p->rchild;
}
while (p != T)
{
Visit(p->data);
pre = parent(T, p);//找到该节点的双亲

if (T == pre)//如果双亲是T,就说明p是根节点,无后继
{
p = T;
}
//如果p是双亲的右孩子,或者双亲无右孩子,则后继为双亲
else if(p==pre->rchild||pre->rtag==1)
{
p = pre;
}
else
{
//若p的双亲有右孩子,后继为双亲右子树上后序遍历的第一个孩子
while (pre->rtag == 0)
{
pre = pre->rchild;
while (pre->ltag == 0)
{
pre = pre->lchild;
}
}
p = pre;
}
}




return OK;
}
/*
中序遍历进行二叉树线索化
*/
void InThreading(BiThrTree p,BiThrTree &pre)
{
if (p)
{
InThreading(p->lchild,pre);//左子树线索化
if (!p->lchild)
{
p->ltag = 1;
p->lchild = pre;
}
if ((!pre->rchild)&&pre->rchild==NULL)
{
pre->rtag = 1;
pre->rchild = p;
}
pre = p;
InThreading(p->rchild, pre);//右子树线索化
}
}
/*
前序遍历进行二叉树线索化
*/
void preThreading(BiThrTree p, BiThrTree &pre)
{
if (p)
{
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 (p->ltag == 0)
preThreading(p->lchild, pre);
if (p->rtag == 0)
preThreading(p->rchild, pre);
}
}

/*
后序遍历进行线索二叉树化
*/
void postThreading(BiThrTree p, BiThrTree &pre)
{
if (p)
{
postThreading(p->lchild, pre);
postThreading(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;
}
}


/*
中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
*/
Status InOrderThreading(BiThrTree &Thrt, BiThrTree T)
{
//建立头结点
if (!(Thrt = (BiThrTree)malloc(sizeof(BiThrNode))))
exit(OVERFLOW);
Thrt->ltag = 0;
Thrt->rtag = 1;

Thrt->rchild = Thrt;//右指针回指
BiThrTree pre;
if (!T)
Thrt->lchild = Thrt;//若二叉树为空,则指针回指
else
{
Thrt->lchild = T;
pre = Thrt;
InThreading(T,pre);//中序遍历进行中序线索化
pre->rchild = Thrt;//最后一个结点线索化
pre->rtag = 1;
Thrt->rchild = pre;
}
return OK;
}

/*
后序遍历二叉树,并将其线索化,原理同中序
*/
Status PostOrderThreading(BiThrTree &Thrt, BiThrTree T)
{
//建立头结点
if (!(Thrt = (BiThrTree)malloc(sizeof(BiThrNode))))
exit(OVERFLOW);
Thrt->ltag = 0;
Thrt->rtag = 1;

Thrt->rchild = Thrt;//右指针回指
BiThrTree pre;

if (!T)
Thrt->lchild = Thrt;//若二叉树为空,则指针回指
else
{
Thrt->lchild = T;
pre = NULL;
postThreading(T, pre);//后序遍历进行后序线索化
pre->rchild = Thrt;
pre->rtag = 1;
Thrt->rchild = pre;//最后一个结点线索化
}
return OK;
}



void main()
{

BiThrTree T1, Thrt1;
cout << "创建线索二叉树,按先序次序输入线索二叉树中结点的值:\n";
CreateBiThrTree(T1);
if (InOrderThreading(Thrt1, T1) == OK)
cout << "成功建立中序线索化链表!\n";
cout << "中序遍历线索二叉树,结果是:\n";
InOrderTraverse_Thr(Thrt1, PrintElement);
cout << endl;

BiThrTree T2;

cout << "创建线索二叉树,按先序次序输入线索二叉树中结点的值:\n";
CreateBiThrTree(T2);
BiThrTree test1 = T2;
preThreading(T2, test1);
cout << "前序遍历线索二叉树,结果是:\n";
PreOrderTraverse_Thr(T2, PrintElement);
cout << endl;

BiThrTree T3,Thrt3;
cout << "创建线索二叉树,按先序次序输入线索二叉树中结点的值:\n";
CreateBiThrTree(T3);
if (PostOrderThreading(Thrt3, T3) == OK)
cout << "成功建立后序序线索化链表!\n";
cout << "后序遍历线索二叉树,结果是:\n";
PostOrderTraverse_Thr(Thrt3, PrintElement);
cout << endl;

system("pause");
}