二叉树的遍历

Published on:

先序遍历(递归版)#

1
2
3
4
5
6
7
8
9
10
//  先序遍历 recursion
void PreOrderRcs(BTNode *b)
{
if(b != NULL)
{
printf("%c",b->data);
PreOrderRcs(b->lchild);
PreOrderRcs(b->rchild);
}
}

中序遍历(递归版)#

1
2
3
4
5
6
7
8
9
10
// 中序遍历 recursion
void InOrderRcs(BTNode *b)
{
if(b != NULL)
{
InOrderRcs(b->lchild);
printf("%c",b->data);
InOrderRcs(b->rchild);
}
}

后序遍历(递归版)#

1
2
3
4
5
6
7
8
9
10
// 后序遍历 recursion
void PostOrderRcs(BTNode *b)
{
if(b != NULL)
{
PostOrderRcs(b->lchild);
PostOrderRcs(b->rchild);
printf("%c",b->data);
}
}

先序遍历(非递归版)#

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

// 前序遍历 non-recursion
void PreOrderNRcs(BTNode *b)
{
if(b != NULL)
{
BTNode *st[MaxSize],*tmp;
int top = 0;
st[top] = b;
//先把跟节点放入栈中
//循环从栈中取出元素
//并访问元素的值(输出结果)
//然后先放右子树,再放左子树
//根据栈的特点,先取左子树,后取右子树
while (top > -1)
{
tmp = st[top--];
printf("%c",tmp->data);
if(tmp->rchild != NULL) st[++top] = tmp->rchild;
if(tmp->lchild != NULL) st[++top] = tmp->lchild;
}
}
else
printf("空树");

}

中序遍历(非递归版)#

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
// 中序遍历 non-recursion
void InOrderNRcs(BTNode *b)
{
if (b != NULL)
{
BTNode *st[MaxSize],*tmp;
int top = -1;
tmp = b;

while (top > -1 || tmp != NULL)
{
// 不断把左子树节点入栈,直到遇到叶子节点
while(tmp != NULL)
{
top++;
st[top] = tmp;
tmp = tmp->lchild;
}
//开始出栈,并且返回右子树阶段
//重新开始查找左子树
if (top > -1)
{
tmp = st[top];
top--;
printf("%c",tmp->data);
tmp = tmp->rchild;
}
}
}
else
printf("空树");

}

后序遍历(非递归版)#

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
// 后序遍历 non-recursion
void PostOrderNRcs(BTNode *b)
{
if (b != NULL)
{
BTNode *st[MaxSize],*tmp; // tmp指针用于存储有孩子节点,默认为NULL
int top = -1,flag;
do
{
while (b != NULL)
{
top++;
st[top] = b;
b = b->lchild;
}
tmp = NULL;
flag = 1;
while (top != -1 && flag)
{
b = st[top];
if(b->rchild == tmp)
{
printf("%c",b->data);
top--;
tmp = b;
}
else
{
b = b->rchild;
flag = 0;
}
}
} while (top != -1);
}
else
printf("空树");

}

层次遍历#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//利用循环队列实现二叉树的层次遍历
void LevelOrder(BTNode *b)
{
BTNode *qu[MaxSize],*tmp;
int front = -1, rear = -1;
rear++;
qu[rear] = b;
while (front != rear)
{
front = (front + 1)%MaxSize;
tmp = qu[front];
printf("%c",tmp->data);
if (tmp->lchild != NULL)
{
rear = (rear + 1)%MaxSize;
qu[rear] = tmp->lchild;
}
if (tmp->rchild != NULL)
{
rear = (rear + 1)%MaxSize;
qu[rear] = tmp->rchild;
}
}
}

完整代码#

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
#include <stdio.h>
#include <stdlib.h>

#define MaxSize 100
typedef char ElemType;

typedef struct node
{
ElemType data; //数据元素
struct node *lchild; //指向左孩子
struct node *rchild; //指向右孩子
} BTNode;

BTNode *CreateBTNode(char *str); //由str串创建二叉树
void DispBTNode(BTNode *b); //以括号表示法输出二叉树
void PreOrderRcs(BTNode *b); //先序遍历的 递归算法
void InOrderRcs(BTNode *b); //中序遍历的 递归算法
void PostOrderRcs(BTNode *b); //后序遍历的 递归算法

void PreOrderNRcs(BTNode *b); //先序遍历的 非递归算法
void InOrderNRcs(BTNode *b); //中序遍历的 非递归算法
void PostOrderNRcs(BTNode *b); //后序遍历的 非递归算法

void LevelOrder(BTNode *b); //层次遍历
void DestroyBTNode(BTNode *b); //销毁二叉树

// 二叉树的遍历(先序遍历,中序遍历,后序遍历,层次遍历)
int main()
{
BTNode *b;
char cstr[] = "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))";
printf(" (1)创建二叉树:");
b = CreateBTNode(cstr);
printf("\n");
printf(" (2)输出二叉树:");
DispBTNode(b);
printf("\n");

printf(" (3)先序遍历(递归)序列:");
PreOrderRcs(b);
printf("\n");
printf(" (4)中序遍历(递归)序列:");
InOrderRcs(b);
printf("\n");
printf(" (5)后序遍历(递归)序列:");
PostOrderRcs(b);
printf("\n");

printf(" (6)先序遍历(非递归)序列:");
PreOrderNRcs(b);
printf("\n");
printf(" (7)中序遍历(非递归)序列:");
InOrderNRcs(b);
printf("\n");
printf(" (8)后序遍历(非递归)序列:");
PostOrderNRcs(b);
printf("\n");

printf(" (9)层次遍历序列:");
LevelOrder(b);
printf("\n");

printf(" (10)释放二叉树b\n");
DestroyBTNode(b);
return 0;
}

BTNode *CreateBTNode(char *str)
{
BTNode *tmp=NULL,*T=NULL,*tmpStack[MaxSize];
int top = -1,i = 0,k;
char ch ;

while ((ch = str[i++]) != '\0')
{
switch (ch)
{
case '(':
tmpStack[++top] = tmp; // 左括号前面的节点入栈
k = 1; // 左括号后面跟着左子树 用 k=1 表示
break;
case ')':
top--; // 出栈
break;
case ',':
k = 2; // 右括号后面跟着右子树 用 k=2 表示
break;
default:
tmp = (BTNode *)malloc(sizeof(BTNode));
tmp->data = ch;
tmp->lchild = tmp->rchild = NULL;
if(T == NULL)
T = tmp; // 第一个节点
else
switch (k)
{
case 1:
tmpStack[top]->lchild = tmp;
break;
case 2:
tmpStack[top]->rchild = tmp;
break;
}

break;
}
}

return T;
}


void DispBTNode(BTNode *b)
{
if(b != NULL)
{
printf("%c",b->data);
if(b->lchild != NULL || b->rchild != NULL)
{ // 有左子树 或者 右子树 时,输出括号
printf("(");
if(b->lchild != NULL)
DispBTNode(b->lchild); // 有左子树时 输出左子树
if(b->rchild != NULL) // 右子树时,输出逗号和右子树
{
printf(",");
DispBTNode(b->rchild);
}
printf(")");
}
}
}

// 前序遍历 recursion
void PreOrderRcs(BTNode *b)
{
if(b != NULL)
{
printf("%c",b->data);
PreOrderRcs(b->lchild);
PreOrderRcs(b->rchild);
}
}
// 中序遍历 recursion
void InOrderRcs(BTNode *b)
{
if(b != NULL)
{
InOrderRcs(b->lchild);
printf("%c",b->data);
InOrderRcs(b->rchild);
}
}

// 后序遍历 recursion
void PostOrderRcs(BTNode *b)
{
if(b != NULL)
{
PostOrderRcs(b->lchild);
PostOrderRcs(b->rchild);
printf("%c",b->data);
}
}

// 前序遍历 non-recursion
void PreOrderNRcs(BTNode *b)
{
if(b != NULL)
{
BTNode *st[MaxSize],*tmp;
int top = 0;
st[top] = b;
//先把跟节点放入栈中
//循环从栈中取出元素
//并访问元素的值(输出结果)
//然后先放右子树,再放左子树
//根据栈的特点,先取左子树,后取右子树
while (top > -1)
{
tmp = st[top--];
printf("%c",tmp->data);
if(tmp->rchild != NULL) st[++top] = tmp->rchild;
if(tmp->lchild != NULL) st[++top] = tmp->lchild;
}
}
else
printf("空树");

}

// 中序遍历 non-recursion
void InOrderNRcs(BTNode *b)
{
if (b != NULL)
{
BTNode *st[MaxSize],*tmp;
int top = -1;
tmp = b;

while (top > -1 || tmp != NULL)
{
// 不断把左子树节点入栈,直到遇到叶子节点
while(tmp != NULL)
{
top++;
st[top] = tmp;
tmp = tmp->lchild;
}
//开始出栈,并且返回右子树阶段
//重新开始查找左子树
if (top > -1)
{
tmp = st[top];
top--;
printf("%c",tmp->data);
tmp = tmp->rchild;
}
}
}
else
printf("空树");

}

// 后序遍历 non-recursion
void PostOrderNRcs(BTNode *b)
{
if (b != NULL)
{
BTNode *st[MaxSize],*tmp; // tmp指针用于存储有孩子节点,默认为NULL
int top = -1,flag;
do
{
while (b != NULL)
{
top++;
st[top] = b;
b = b->lchild;
}
tmp = NULL;
flag = 1;
while (top != -1 && flag)
{
b = st[top];
if(b->rchild == tmp)
{
printf("%c",b->data);
top--;
tmp = b;
}
else
{
b = b->rchild;
flag = 0;
}
}
} while (top != -1);
}
else
printf("空树");

}


//利用循环队列实现二叉树的层次遍历
void LevelOrder(BTNode *b)
{
BTNode *qu[MaxSize],*tmp;
int front = -1, rear = -1;
rear++;
qu[rear] = b;
while (front != rear)
{
front = (front + 1)%MaxSize;
tmp = qu[front];
printf("%c",tmp->data);
if (tmp->lchild != NULL)
{
rear = (rear + 1)%MaxSize;
qu[rear] = tmp->lchild;
}
if (tmp->rchild != NULL)
{
rear = (rear + 1)%MaxSize;
qu[rear] = tmp->rchild;
}
}
}

//销毁二叉树
void DestroyBTNode(BTNode *b)
{
if (b != NULL)
{
DestroyBTNode(b->lchild);
DestroyBTNode(b->rchild);
free(b);
}
}