二叉樹是一種非常重要的數據結構,很多其它數據結構都是基於二叉樹的基礎演變而來的。對於二叉樹,有前序、中序以及後序三種遍歷方法。因爲樹的定義本身就是遞歸定義,因此採用遞歸的方法去實現樹的三種遍歷不僅容易理解而且代碼很簡潔。而對於樹的遍歷若採用非遞歸的方法,就要採用棧去模擬實現。在三種遍歷中,前序和中序遍歷的非遞歸算法都很容易實現,非遞歸後序遍歷實現起來相對來說要難一點。
這裏用的是我自己實現的棧結構純C語言實現,有需要的同學可自行更改源碼
typedef int TElemType;
typedef struct BiTNode{
TElemType data ;
struct BiTNode * lchild, * rchild;
}BiTNode, * BiTree;
int CreateBiTree(BiTree &T)
{
char ch;
scanf("%c",&ch);
if(ch == '#') T = NULL;
else{
if(!(T = (BiTNode *)malloc(sizeof(BiTNode))))
return 0;
T->data = ch; //生成根節點
CreateBiTree(T->lchild); //生成左子樹
CreateBiTree(T->rchild); //生成右子樹
}
return 1;
}
void visit(TElemType e)
{
printf("%c",e);
}
//中序非遞歸遍歷二叉樹
int InOrderTraverse(BiTree T,void (* visit)(TElemType e))
{
SqStack S;
InitStack(S);
Push(S,T);//根指針入棧
BiTree p;
while(!StackEmpty(S))
{
while(GetTop(S,p)&&p) Push(S,p->lchild);
Pop(S,p);//刪除空節點
if(!StackEmpty(S))
{
Pop(S,p);
visit(p->data);
Push(S,p->rchild);
}
}
return 1;
}
//先序非遞歸遍歷
int PreOrderTraverse(BiTree T,void (* visit)(TElemType e))
{
SqStack S;
InitStack(S);
Push(S,T);//根指針入棧
BiTree p;
while(!StackEmpty(S))
{
while(GetTop(S,p)&&p)
{
visit(p->data);
Push(S,p->lchild);
}
Pop(S,p);//刪除空節點
if(!StackEmpty(S))
{
Pop(S,p);
Push(S,p->rchild);
}
}
return 1;
}
int LastOrderTraverse(BiTree T,void (* visit)(TElemType e))
{
SqStack S;
InitStack(S);
Push(S,T);//根指針入棧
BiTree p;
BiTree pre;//前一個節點;
while(!StackEmpty(S))
{
GetTop(S,p);
if( (p->lchild==NULL&&p->rchild == NULL) || (pre!=NULL&&(p->lchild==pre||p->rchild==pre)))
{
Pop(S,p);
visit(p->data);
pre = p;
}else{
if(p->rchild!=NULL)
Push(S,p->rchild);
if(p->lchild!=NULL)
Push(S,p->lchild);
}
}
return 1;
}
int main()
{
char s[50] ;
char ch;
BiTree T;
printf("請輸入字符串構造二叉樹\n");
CreateBiTree(T);
printf("中序非遞歸遍歷二叉樹\n");
InOrderTraverse(T,visit);
printf("\n");
printf("先序非遞歸遍歷二叉樹\n");
PreOrderTraverse(T,visit);
printf("\n");
printf("後序非遞歸遍歷二叉樹\n");
LastOrderTraverse(T,visit);
printf("\n");
return 0;
}