1. 程式人生 > >資料結構二叉樹三種非遞迴的遍歷

資料結構二叉樹三種非遞迴的遍歷

#include <stdio.h>
#include <malloc.h>
#define MAX 30
typedef struct TiNode
{
char date;
struct TiNode *lchild;
struct TiNode *rchild;
}*BiTree;
void create(BiTree *);//注意這裡傳參是二級指標。不在解釋
void PreOreder(BiTree);
void InOerder(BiTree);
void PostOreder(BiTree);
BiTree search(BiTree,char);
void LevelOrder(BiTree);
int main(void)
{
BiTree BT,BN;
char ch;
printf("請輸入建立的二叉樹('#'表示子樹為空)");
create(&BT);
printf("非遞迴先序遍歷為:");
PreOreder(BT);
printf("\n");
printf("非遞迴後序序遍歷為:");
PostOreder(BT);
printf("\n");
printf("非遞迴中序遍歷為:");
InOerder(BT);
printf("\n");


getchar();
printf("請輸入你要查詢的值:");
scanf("%c",&ch);
BN=search(BT,ch);
if(BN==NULL)
printf("Not Found!\n");
else
printf("查詢成功!\n");
printf("該二叉樹的層次遍歷為:");
LevelOrder(BT);


return 0;
}
void create(BiTree *BT)
{
char ch;
ch=getchar();
if(ch=='#')
*BT=NULL;
else
{
(*BT)=(BiTree)malloc(sizeof(struct TiNode));
(*BT)->date=ch;
create(&(*BT)->lchild);
create(&(*BT)->rchild);
}
return ;
}
void PreOreder(BiTree BT)
{
BiTree Stack[MAX],BN=BT;
int top=0;
if(BT==NULL)
return;
while(top!=0||BN!=NULL)
{
while(BN)
{
printf("%c ",BN->date);//先序就是先訪問
Stack[++top]=BN;
BN=BN->lchild;
}
if(top!=0)//說明該節點的左子樹為空,我們此時訪問的是右子樹(BN==null),而且出棧一定棧不為空的前提下
{
BN=Stack[top--];
BN=BN->rchild;
}
}
return ;
}
void InOerder(BiTree BT)//接下來我我們研究一下中序遍歷的做法
{
BiTree Stack[MAX],BN=BT;
int top=0;
if(BT==NULL)return;
while(BN||top!=0)//當棧為空且樹為空的時候。退出迴圈
{
while(BN)//將左子樹節點都入棧,直到左子樹為空
{
Stack[++top]=BN;
BN=BN->lchild;
}
if(top!=0)//說明左子樹為空了
{

BN=Stack[top--];//我們是先出棧接著訪問訪問的額
printf("%c ",BN->date);
BN=BN->rchild;
}
}
return ;
}
 void PostOreder(BiTree BT)//此時後序遍歷。比較好玩啊
 {
BiTree Stack[MAX],pPre=NULL,pCur=BT;
int top=0;
if(BT==NULL)
return;
Stack[++top]=BT;//我們首先將根節點入棧。
while(top!=0)
{
pCur=Stack[top];//始終指向棧頂元素
if((pCur->lchild==NULL&&pCur->rchild==NULL)||(pPre!=NULL&&(pCur->lchild==pPre||pCur->rchild==pPre)))
{//如果該節點的左右子樹為空或者該節點存在左子樹或者右子樹。但是左右子樹都被訪問過了。
//這裡pPre就是上一個出棧的節點,pCur就是新棧頂的節點,如果上一個出棧的節點新棧頂的左右子樹,代表訪問過了他的子樹,直接訪問根節點)
printf("%c ",pCur->date);
pPre=Stack[top--];//而pPre指向上一個要出棧的元素
}
else
{
if(pCur->rchild!=NULL)//壓棧先壓棧右子樹。接著在押左子樹。(因為我們後序遍歷先左後右接著根節點,棧是先進先出)
Stack[++top]=pCur->rchild;
if(pCur->lchild!=NULL)
Stack[++top]=pCur->lchild;
}
}
 return ;
 }
 BiTree search(BiTree BT,char ch)
 {
BiTree BN=NULL;
if(!BT)
return NULL;
if(BT->date==ch)
return BT;
BN=search(BT->lchild,ch);
if(!BN)
BN=search(BT->rchild,ch);
return BN;
 }
 void LevelOrder(BiTree BT)
 {
BiTree Queue[MAX],BN;
int rear,front;
rear=front=0;
Queue[rear++]=BT;//我們首先將根節點壓入棧。
while(rear!=front)//如果佇列不為空的話
{
BN=Queue[front++];
printf("%c ",BN->date);
if(BN->lchild)
Queue[rear++]=BN->lchild;
if(BN->rchild)
Queue[rear++]=BN->rchild;
}
printf("\n");
 return;
 }