1. 程式人生 > >二叉樹利用佇列實現層次遍歷

二叉樹利用佇列實現層次遍歷

這裡先提一句為什麼之前樹的建立可以由前序遍歷的方法搞定,原因是前序遍歷的時候把所有的空節點都包含在內了,如果僅僅只有非空節點的前序遍歷輸入,是無法得到單一二叉樹的,例如給出了一個前序遍歷順序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

執行效果如下