若 p 所指结点不为空,则访问该结点,然后将该结点的地址入栈,然后再将 p 指向其左孩子结点;若p所指向的结点为空,则从堆栈中退出栈顶元素(某个结点的地址),将 p 指向其右孩子结点。重复上述过程,直到 p = NULL 且堆栈为空,遍历结束。
中序遍历算法描述
若 p 所指结点不为空,则将该结点的地址 p 入栈,然后再将 p 指向其左孩子结点;若 p 所指向的结点为空,则从堆栈中退出栈顶元素(某个结点的地址)送 p,并访问该结点,然后再将 p 指向该结点的右孩子结点。重复上述过程,直到 p = NULL 且堆栈为空,遍历结束。
后序算法描述
当 p 指向某一结点时,不能马上对它进行访问,而要先访问它的左子树,因而要将此结点的地址入栈;当其左子树访问完毕后,再次搜索到该结点时(该结点地址通过退栈得到),还不能对它进行访问,还需要先访问它的右子树,所以,再一次将该结点的地址入栈。只有当该结点的右子树访问完毕后回到该结点时,才能访问该结点。为了标明某结点是否可以访问,引入一个标志变量flag,当 flag = 0 时表示该结点暂不访问, flag = 1 时表示该结点可以访问。 flag 的值随同该结点的地址一起入栈和出栈。因此,算法中设置了两个堆栈,其中 STACK1 存放结点的地址, STACK2 存放标志变量 flag,两个堆栈使用同一栈顶指针 top,且 top 的初始值为 −1。
代码实现
#include<stdio.h>#include<malloc.h>#include<iostream>usingnamespacestd;
#define MaxSize 100typedefstruct BTNode
{
char data;
struct BTNode *lchild, *rchild;
}BTNode;
void CreateTree(BTNode *& T)
{
char c;
cin >> c;
if (c == '0')
{
T = NULL;
}
else
{
T = (BTNode*)malloc(sizeof(BTNode));
T->data = c;
CreateTree(T->lchild);
CreateTree(T->rchild);
}
}
void Visit(BTNode *p)
{
printf("%c ", p->data);
}
void preOrder(BTNode *T)
{
BTNode *p, *s[MaxSize];
int top = -1;
p = T;
while (p != NULL || top != -1)
{
while (p != NULL)
{
Visit(p);
s[++top] = p;
p = p->lchild;
}
p = s[top--];
p = p->rchild;
}
}
void inOrder(BTNode *T)
{
BTNode *p, *s[MaxSize];
int top = -1;
p = T;
while (p != NULL || top != -1)
{
while (p != NULL)
{
s[++top] = p;
p = p->lchild;
}
p = s[top--];
Visit(p);
p = p->rchild;
}
}
void postOrder(BTNode *T)
{
BTNode *p, *s1[MaxSize];
int s2[MaxSize];
int flag, top = -1;
p = T;
while (p != NULL || top != -1)
{
while (p != NULL)
{
s1[++top] = p;
s2[top] = 0;
p = p->lchild;
}
p = s1[top];
flag = s2[top--];
if (flag == 0)
{
s1[++top] = p;
s2[top] = 1;
p = p->rchild;
}
else
{
Visit(p);
p = NULL;
}
}
}
int main()
{
//freopen("E:\input.txt", "r", stdin);
BTNode *T;
CreateTree(T);
preOrder(T);
printf("\n");
getchar();
inOrder(T);
printf("\n");
getchar();
postOrder(T);
printf("\n");
return0;
}