基于栈和队列实现二叉树的遍历
来源:互联网 发布:java后台接收上传图片 编辑:程序博客网 时间:2024/05/18 14:12
一般我们遍历二叉树的时候用的是递归,用递归实现比较简单,代码如下:
通过改变printf语句的位置便可以实现前序和中序遍历。
下面我们来看看如何基于栈实现二叉树的遍历,可以把二叉树分为root,left,right三个部分
前序遍历的次序为root,left,right;
中序遍历的次序为left,root,right;
后序遍历的次序为left,right,root;
先讨论前序遍历和中序遍历,显然可以通过下面的步骤实现
1.不断将左子树入栈,直到左子树为空
2.不断出栈,直到出栈元素的右子树不为空
3.如果栈不为空或当前根结点不为空,重复步骤1和2
前序遍历是在步骤1中将入栈的树的根结点输出,而中序则是在步骤2中将出栈的树的根结点输出
代码如下:
最后要如何基于栈实现二叉树的后序遍历呢?通过观察可以发现
前序遍历的次序为root,left,right;
后序遍历的次序为left,right,root;
将前序遍历的left和right调换,在倒过来输出,便可以实现后序遍历!
因此我们可以通过修改一下上面的代码实现后序遍历,方法如下:
1,将前序遍历代码中的left 和right 对调,并数据存在栈S中。
2,前序遍历完后,将栈S中的数据逐个出栈并打印即可。
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/****************
基于递归实现后序遍历,
*****************/
void
PostOrderTraverse(NODE* pRoot) {
if
(pRoot == NULL) {
return
;
}
else
{
PostOrderTraverse(pRoot->pLeft);
PostOrderTraverse(pRoot->pRight);
printf
(
"%c"
, pRoot->chValue);
}
return
;
}
通过改变printf语句的位置便可以实现前序和中序遍历。
下面我们来看看如何基于栈实现二叉树的遍历,可以把二叉树分为root,left,right三个部分
前序遍历的次序为root,left,right;
中序遍历的次序为left,root,right;
后序遍历的次序为left,right,root;
先讨论前序遍历和中序遍历,显然可以通过下面的步骤实现
1.不断将左子树入栈,直到左子树为空
2.不断出栈,直到出栈元素的右子树不为空
3.如果栈不为空或当前根结点不为空,重复步骤1和2
前序遍历是在步骤1中将入栈的树的根结点输出,而中序则是在步骤2中将出栈的树的根结点输出
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/****************
基于栈实现前序和中序遍历
*****************/
void
OrderTraverseByStack(NODE* pRoot) {
NODE* Stack[1000];
int
top = 0;
while
(top > 0 || pRoot != NULL) {
for
(; pRoot != NULL; pRoot = pRoot->pLeft) {
Stack[top++] = pRoot;
//前序遍历
//printf("%c",pRoot->chValue);
}
for
(; pRoot == NULL&&top > 0; pRoot = pRoot->pRight) {
pRoot = Stack[--top];
//中序遍历
//printf("%c", pRoot->chValue);
}
}
}
最后要如何基于栈实现二叉树的后序遍历呢?通过观察可以发现
前序遍历的次序为root,left,right;
后序遍历的次序为left,right,root;
将前序遍历的left和right调换,在倒过来输出,便可以实现后序遍历!
因此我们可以通过修改一下上面的代码实现后序遍历,方法如下:
1,将前序遍历代码中的left 和right 对调,并数据存在栈S中。
2,前序遍历完后,将栈S中的数据逐个出栈并打印即可。
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/****************
基于栈实现后序遍历
*****************/
void
PostOrderTraverseByStack(NODE* pRoot) {
NODE *StackA[1000],*StackB[1000];
int
topA = 0,topB = 0;
while
(topA > 0 || pRoot != NULL) {
for
(; pRoot != NULL;pRoot = pRoot->pRight) {
StackA[topA++] = pRoot;
StackB[topB++] = pRoot;
}
for
(; pRoot == NULL&&topA > 0; pRoot = pRoot->pLeft) {
pRoot = StackA[--topA];
}
}
while
(topB > 0) {
printf
(
"%c"
, StackB[--topB]->chValue);
}
}
基于队列实现二叉树的层遍历,原理上和广度优先搜索算法相似,首先将根结点入队,然后判断队列是否为空,
不为空则从队列中出队一个结点进行处理,对出队结点,先输出其数据,然后依次将左右孩子结点入队,如此循环
直到队列为空结束,则已经完成对二叉树的层序遍历,下面给出代码:
/****************************根据层序遍历访问,基于队列操作****************************/void LevelOrderTraverseByQueue(NODE* pRoot) {NODE* Queue[1000], *p = NULL;int start = 0, end = 0;Queue[end++] = pRoot;if (pRoot == NULL) return;while (start != end) {p = Queue[start++];printf("%c", p->chValue);if (p->pLeft) Queue[end++] = p->pLeft;if (p->pRight) Queue[end++] = p->pRight;}}
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
#include<stdio.h>
#include<stdlib.h>
#define TREELEN 6
struct
NODE {
NODE* pLeft;
NODE* pRight;
char
chValue;
};
void
ReBuild(
char
* pPreOrder,
char
* pInOrder,
int
nTreeLen,NODE** pRoot) {
if
(pPreOrder == NULL || pInOrder == NULL) {
return
;
}
NODE* pTemp =(NODE* )
malloc
(
sizeof
(NODE));
pTemp->chValue = *pPreOrder;
pTemp->pLeft = NULL;
pTemp->pRight = NULL;
if
(*pRoot == NULL) {
*pRoot = pTemp;
}
if
(nTreeLen == 1) {
return
;
}
char
* pOrgInOrder = pInOrder;
char
* pLeftEnd = pInOrder;
int
nTempLen = 0;
while
(*pPreOrder != *pLeftEnd) {
if
(pPreOrder == NULL || pLeftEnd == NULL) {
return
;
}
nTempLen++;
if
(nTempLen > nTreeLen) {
break
;
}
pLeftEnd++;
}
int
nLeftLen = 0;
nLeftLen = (
int
)(pLeftEnd - pOrgInOrder);
int
nRightLen = 0;
nRightLen = nTreeLen - nLeftLen - 1;
if
(nLeftLen > 0) {
ReBuild(pPreOrder+1, pInOrder, nLeftLen, &((*pRoot)->pLeft));
}
if
(nRightLen > 0) {
ReBuild(pPreOrder + nLeftLen + 1, pInOrder + nLeftLen +1, nRightLen, &((*pRoot)->pRight));
}
}
/****************
基于递归实现后序遍历,
*****************/
void
PostOrderTraverse(NODE* pRoot) {
if
(pRoot == NULL) {
return
;
}
else
{
PostOrderTraverse(pRoot->pLeft);
PostOrderTraverse(pRoot->pRight);
printf
(
"%c"
, pRoot->chValue);
}
return
;
}
/****************
基于栈实现前序和中序遍历
*****************/
void
OrderTraverseByStack(NODE* pRoot) {
NODE* Stack[1000];
int
top = 0;
while
(top > 0 || pRoot != NULL) {
for
(; pRoot != NULL; pRoot = pRoot->pLeft) {
Stack[top++] = pRoot;
//前序遍历
//printf("%c",pRoot->chValue);
}
for
(; pRoot == NULL&&top > 0; pRoot = pRoot->pRight) {
pRoot = Stack[--top];
//中序遍历
printf
(
"%c"
, pRoot->chValue);
}
}
}
/****************
基于栈实现后序遍历
*****************/
void
PostOrderTraverseByStack(NODE* pRoot) {
NODE *StackA[1000],*StackB[1000];
int
topA = 0,topB = 0;
while
(topA > 0 || pRoot != NULL) {
for
(; pRoot != NULL;pRoot = pRoot->pRight) {
StackA[topA++] = pRoot;
StackB[topB++] = pRoot;
}
for
(; pRoot == NULL&&topA > 0; pRoot = pRoot->pLeft) {
pRoot = StackA[--topA];
}
}
while
(topB > 0) {
printf
(
"%c"
, StackB[--topB]->chValue);
}
}
/****************************
根据层序遍历访问,基于队列操作
****************************/
void LevelOrderTraverseByQueue(NODE* pRoot) {
NODE* Queue[1000], *p = NULL;
int start = 0, end = 0;
Queue[end++] = pRoot;
if (pRoot == NULL) return;
while (start != end) {
p = Queue[start++];
printf("%c", p->chValue);
if (p->pLeft) Queue[end++] = p->pLeft;
if (p->pRight) Queue[end++] = p->pRight;
}
}
int
main() {
NODE* pRoot = NULL;
char
pre[TREELEN] = {
'a'
,
'b'
,
'd'
,
'e'
,
'c'
,
'f'
};
char
in[TREELEN] = {
'd'
,
'b'
,
'e'
,
'a'
,
'f'
,
'c'
};
ReBuild(pre, in, TREELEN, &pRoot);
printf
(
"\n通过栈实现的中序遍历结果:\n"
);
OrderTraverseByStack(pRoot);
printf
(
"\n通过递归实现的后序遍历结果:\n"
);
PostOrderTraverse(pRoot);
printf
(
"\n通过栈实现的后序遍历结果:\n"
);
PostOrderTraverseByStack(pRoot);
printf("\n通过队列实现的层序遍历结果:\n");
LevelOrderTraverseByQueue(pRoot);
getchar
();
return
0;
}
1 0
- 基于栈和队列实现二叉树的遍历
- 队列和堆栈实现二叉树的遍历
- 队列实现二叉树的遍历
- 遍历二叉树——递归和非递归(栈和队列的应用)实现
- 二叉树遍历之栈和队列
- 栈,队列和二叉树的实现
- 基于栈来实现二叉树的先根遍历
- 基于二叉堆实现的优先队列和堆排序
- 二叉树(利用栈和队列实现递归和非递归遍历,构建等)
- 二叉树的深度优先遍历(栈)和广度优先遍历(队列)
- 二叉树的深度优先遍历(栈)和广度优先遍历(队列)
- 二叉树的宽度优先遍历(队列实现)
- 队列实现 二叉树的宽度优先遍历
- 队列实现二叉树的层序遍历
- 利用队列实现二叉树的层次遍历
- 数据结构 二叉树层序遍历的队列实现
- 二叉树的实现和二叉数的遍历实现
- 二叉树前中后序遍历的递归版本和非递归版本、队列实现的层次遍历
- Android多线程问题。android.os.NetworkOnMainThreadException
- python04-错误、调试和测试
- Objective-C 和 Core Foundation 对象相互转换的内存管理总结
- <php+mysql>从PHP连接数据库,以及mysqli_connect()不能使用localhost的解答
- java *** 制作圣诞贺卡
- 基于栈和队列实现二叉树的遍历
- 请用fontAwesome代替网页icon小图标
- SVN提交版本时强制填写备注
- 数据结构课程设计之航空订票系统
- VelocityLayoutViewResolver和VelocityViewResolver的区别
- securityImage
- Day01 - Xcode常用快捷键、高级语言源码的编译到运行、三码运算、基础类型所占字节与取值范围
- poj 2202 Squares(求正方形个数)
- 欢迎使用CSDN-markdown编辑器