二叉樹利用佇列實現層次遍歷
阿新 • • 發佈:2019-01-10
這裡先提一句為什麼之前樹的建立可以由前序遍歷的方法搞定,原因是前序遍歷的時候把所有的空節點都包含在內了,如果僅僅只有非空節點的前序遍歷輸入,是無法得到單一二叉樹的,例如給出了一個前序遍歷順序AB
那麼有可能是兩種情況,如下圖所示
A 或者 A
B B
甚至給出它的後序遍歷也不可以,如果得知兩種遍歷順序希望獲得唯一的二叉樹,至少要給出其中序遍歷
轉回主題,如何利用佇列實現層序遍歷呢
佇列實現:遍歷從根節點開始,首先將根節點入隊,然後開始執行迴圈:結點出隊、訪問該節點、其左右兒子入隊
層序遍歷的基本過程是:
先根節點入隊,然後:
1.從佇列中取出一個
2.訪問該元素所指的結點
3.若該元素所指結點的左、右孩子結點非空,則將其左、右孩子的指標順序入隊
實現程式碼如下
二叉樹和之前的一樣#include "stdio.h" #include "stdlib.h" #define ERROR 0 typedef struct tree { char data; struct tree *lchild; struct tree *rchild; }*Ptree; typedef Ptree ElementType; struct Node{ ElementType Data; struct Node *Next; }; struct QNode{ struct Node *rear; struct Node *front; }; typedef struct QNode *Queue; //建立樹 Ptree createTree(); //建立佇列 Queue CreateQueue(); //刪除佇列頭元素 ElementType DeleteQ(Queue PtrQ); //在隊尾插入元素 void InsertQ(ElementType item,Queue PtrQ); //判斷是否空 int IsEmpty(Queue Q); //利用佇列層次遍歷 void LevelOrderTraversal(Ptree BT); void main() { Ptree t; printf("先序建立二叉樹,用空格代表虛結點:\n"); t=createTree(); printf("\n"); printf("利用佇列的層次遍歷:\n"); LevelOrderTraversal(t); printf("\n"); system("pause"); } //樹的建立 Ptree createTree() { char ch; Ptree t; ch=getchar(); //輸入二叉樹資料 if(ch==' ') //判斷二叉樹是否為空 t=NULL; else { t=(Ptree)malloc(sizeof(Ptree)); //二叉樹的生成 t->data=ch; t->lchild=createTree(); t->rchild=createTree(); } return t; } //建立佇列 Queue CreateQueue(){ Queue PtrQ; PtrQ=(Queue)malloc(sizeof(struct QNode)); struct Node *rear; struct Node *front; rear =(Node*)malloc(sizeof(struct Node)); rear=NULL; front =(Node*)malloc(sizeof(struct Node)); front=NULL; PtrQ->front=front; PtrQ->rear=rear; return PtrQ; }; //刪除佇列頭元素 ElementType DeleteQ(Queue PtrQ){ struct Node *FrontCell; ElementType FrontElem; if(IsEmpty(PtrQ)){ printf("佇列空"); return ERROR; } FrontCell=PtrQ->front; if(PtrQ->front==PtrQ->rear) PtrQ->front=PtrQ->rear=NULL; else{ PtrQ->front=PtrQ->front->Next; } FrontElem=FrontCell->Data; free(FrontCell); return FrontElem; } //在隊尾插入元素 void InsertQ(ElementType item,Queue PtrQ){ struct Node *FrontCell; FrontCell=(Node*)malloc(sizeof(struct Node)); FrontCell->Data=item; FrontCell->Next=NULL; if(IsEmpty(PtrQ)){ PtrQ->front=FrontCell; PtrQ->rear=FrontCell; } else{ PtrQ->rear->Next=FrontCell; PtrQ->rear=FrontCell; } }; //判斷是否空 int IsEmpty(Queue Q){ return(Q->front==NULL); }; //利用佇列層次遍歷 void LevelOrderTraversal(Ptree BT) { Queue Q; Ptree T; if(!BT) return; Q=CreateQueue(); T=BT; InsertQ(T,Q); while(!IsEmpty(Q)){ T=DeleteQ(Q); printf("%c",T->data); if(T->lchild) InsertQ(T->lchild,Q); if(T->rchild) InsertQ(T->rchild,Q); } };
A
B C
D F G I
E H
執行效果如下