若 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;
}