二叉树的前序非递归遍历
前面学习过二叉树的前序遍历,使用递归的方式。简单回顾一下:
Status PerOrder(BiTree T) {
//前序遍历二叉树
if (T != NULL) {
Visit(T);
PerOrder(T->lchild);
PerOrder(T->rchild);
}
return OK;
}
接下来用非递归的方式实现二叉树的前序遍历。我们可以利用栈来辅助实现该功能。
定义二叉树的结构体:
typedef struct BiTree{
//定义二叉树
char data;
struct BiTree* lchild;
struct BiTree* rchild;
}BiTNode,* BiTree;
定义辅助栈的结构体。注意栈中应存放的数据类型:
typedef struct {
//定义栈
BiTree base;
BiTree top;
int stacksize;
}SqStack;
在遍历操作中,我们需要用到栈的操作有初始化、出栈、入栈、判空。具体代码见附录。
算法思路
利用前序遍历的性质,访问顺序应该是“根,左,右”。我们首先让根结点入栈,每次入栈一个元素,就访问他。一直循环直到到达二叉树最左边的结点,也就是将遍历指针指向最左边的结点。之后出栈,每出栈一个元素,将遍历指针指向该元素的右子树,如果存在,进行与之前一样的操作,循环找到该子树当中最左端的结点。若不存在右子树,继续出栈一个元素,找该元素的右子树,以此类推。
Status PreOrderTraverse(BiTree T) {
SqStack S;
InitStack(&S); //初始化一个栈
BiTree P = T; //遍历指针
BiTree Q = T;
while (P || !StackEmpty(S)) {
//若P不为空或者栈不空则循环
if (P) {
Visit(P); //进栈就访问
Push(&S, *P); //入栈
P = P->lchild; //向左走到尽头
}
else {
Pop(&S, Q); //出栈
P = Q;
P = P->rchild; //访问出栈元素的右孩子
}
}
return OK;