本题要求采用栈实现对二叉树的非递归遍历,包括先序、中序和后序三种遍历方式。
输入格式:
输入序列是按照先序序列输入,以@表示空结点
输出格式:
先序、中序和后序遍历序列分别按行输出
ABC@@D@@E@FG@@@
输出样例:
ABCDEFG
CBDAEGF
CDBGFEA
代码示例:
#include <stdio.h>
#include <stdlib.h>
typedef struct BTNode
{
char ele;
struct BTNode* LChild;
struct BTNode* RChild;
}BTNode, * BTree;
typedef struct
{
BTNode* data[100]; //每个栈单元存放的是一个二叉树结点,且要链式存储
int top;
} Stack;
void InitStack(Stack* s)
{
s->top = -1;
}
void Push(Stack* s, BTNode* p)
{
s->data[++s->top] = p;
}
BTNode* Pop(Stack* s)
{
if (!IsEmpty(s))
return s->data[s->top--];
else
return NULL;
}
int IsEmpty(Stack* s)
{
if (s->top == -1)
return 1;
else
return 0;
}
BTree GetTop(Stack* s)
{
if (s->top > -1)
return s->data[s->top];
else
return NULL;
}
BTree CreateTree()
{
char ch;
scanf("%c", &ch);
if (ch == '@')
return NULL;
while (ch != '@')
{
BTNode* p = (BTNode*)malloc(sizeof(BTNode)); //每次都要构建一个新的结点。
p->ele = ch;
p->LChild = CreateTree();
p->RChild = CreateTree();
return p;
}
}
//非递归先序遍历输出
void FirstOrder(BTree root)
{
Stack s;
InitStack(&s);
BTNode* p = root;
while (p != NULL || !IsEmpty(&s))
{
if (p != NULL)
{
printf("%c", p->ele);
Push(&s, p);
p = p->LChild;
}
else
{
p = Pop(&s);
p = p->RChild;
}
}
printf("\n");
}
//非递归中序遍历输出
void MiddleOrder(BTree root)
{
Stack s;
InitStack(&s);
BTree p = root;
while (p != NULL || !IsEmpty(&s))
{
if (p != NULL)
{
Push(&s, p);
p = p->LChild;
}
else
{
p = Pop(&s);
printf("%c", p->ele);
p = p->RChild;
}
}
printf("\n");
}
//非递归后序遍历输出
void LastOrder(BTree root)
{
Stack s;
InitStack(&s);
BTree p = root;
BTree q = NULL;
while (p != NULL || !IsEmpty(&s))
{
if (p != NULL)
{
Push(&s, p);
p = p->LChild;
}
else
{
p = GetTop(&s); //只访问栈顶,不退栈,因为只是用来判断右孩子的情况
if (p->RChild == NULL || p->RChild == q) //右孩子为空,或者已经访问过
{
printf("%c", p->ele);
q = p; //记录已访问过的结点
p = Pop(&s);
p = NULL; //p要置空,否则会重复进入刚访问过的结点的左子树
}
else
{
p = p->RChild; //右孩子存在,于是访问
}
}
}
printf("\n");
}
int main()
{
BTree root = NULL;
root = CreateTree();
FirstOrder(root);
MiddleOrder(root);
LastOrder(root);
return 0;
}