【練習】二叉樹的遍歷

Time-space發表於2017-10-31

1.按層遍歷

void oper(ChainBinTree *p) //操作二叉樹結點資料 
{
     printf("%c ",p->data); //輸出資料
     return;
}

void BinTree_Level(ChainBinTree *bt,void (*oper)(ChainBinTree *p)) //按層遍歷 
{
     ChainBinTree *p;
     ChainBinTree *q[QUEUE_MAXSIZE]; //定義一個順序棧 
     int head=0,tail=0;//隊首、隊尾序號 
     if(bt)//若隊首指標不為空     
     {
         tail=(tail+1)%QUEUE_MAXSIZE;//計算迴圈佇列隊尾序號 
         q[tail] = bt;//將二叉樹根指標進隊
     }
     while(head!=tail) //佇列不為空,進行迴圈 
     {
         head=(head+1)%QUEUE_MAXSIZE; //計算迴圈佇列的隊首序號 
         p=q[head]; //獲取隊首元素 
         oper(p);//處理隊首元素 
         if(p->left!=NULL) //若結點存在左子樹,則左子樹指標進隊 
         {
             tail=(tail+1)%QUEUE_MAXSIZE;//計算迴圈佇列的隊尾序號 
             q[tail]=p->left;//將左子樹指標進隊 
         }

         if(p->right!=NULL)//若結點存在右孩子,則右孩子結點指標進隊 
         {
             tail=(tail+1)%QUEUE_MAXSIZE;//計算迴圈佇列的隊尾序號 
             q[tail]=p->right;//將右子樹指標進隊 
         }
     }
     return; 
}

  在整個佇列的處理中,首先從根節點開始,將每層的結點逐步進入佇列,這樣就可以得到按層遍歷的效果。


2.遞迴遍歷二叉樹

先序遍歷

void BinTree_DLR(ChainBinTree *bt,void (*oper)(ChainBinTree *p))  //先序遍歷 
{     
     if(bt)//樹不為空,則執行如下操作 
     {
         oper(bt); //處理結點的資料 
         BinTree_DLR(bt->left,oper);
         BinTree_DLR(bt->right,oper);
     }
     return; 
}

中序遍歷

void BinTree_LDR(ChainBinTree *bt,void(*oper)(ChainBinTree *p))  //中序遍歷 
{
     if(bt)//樹不為空,則執行如下操作 
     {
         BinTree_LDR(bt->left,oper); //中序遍歷左子樹
         oper(bt);//處理結點資料 
         BinTree_LDR(bt->right,oper); //中序遍歷右子樹/
     }
     return; 
} 

後序遍歷

void BinTree_LRD(ChainBinTree *bt,void (*oper)(ChainBinTree *p)) //後序遍歷
{
     if(bt)
     {
         BinTree_LRD(bt->left,oper); //後序遍歷左子樹 
         BinTree_LRD(bt->right,oper); //後序遍歷右子樹/
         oper(bt); //處理結點資料
     }
     return; 
}

3.非遞迴遍歷二叉樹

  利用棧可以實現遍歷二叉樹的非遞迴演算法。

先序遍歷

void PreOrderTraverse2(BiTree T)
/*先序遍歷二叉樹的非遞迴實現*/
{
    BiTree stack[MaxSize];              /*定義一個棧,用於存放結點的指標*/
    int top;                            /*定義棧頂指標*/
    BitNode *p;                         /*定義一個結點的指標*/
    top=0;                          /*初始化棧*/
    p=T;
    while(p!=NULL||top>0)
    {
        while(p!=NULL)                  /*如果p不空,訪問根結點,遍歷左子樹*/
        {
            printf("%2c",p->data);          /*訪問根結點*/
            stack[top++]=p;                 /*將p入棧*/
            p=p->lchild;                /*遍歷左子樹*/
        }
        if(top>0)                       /*如果棧不空*/
        {
            p=stack[--top];                 /*棧頂元素出棧*/
            p=p->rchild;                    /*遍歷右子樹*/
        }
    }
}

中序遍歷

void InOrderTraverse2(BiTree T)
/*中序遍歷二叉樹的非遞迴實現*/
{
    BiTree stack[MaxSize];              /*定義一個棧,用於存放結點的指標*/
    int top;                            /*定義棧頂指標*/
    BitNode *p;                         /*定義一個結點的指標*/
    top=0;                          /*初始化棧*/
    p=T;
    while(p!=NULL||top>0)
    {
        while(p!=NULL)                  /*如果p不空,訪問根結點,遍歷左子樹*/
        {
            stack[top++]=p;                 /*將p入棧*/
            p=p->lchild;                /*遍歷左子樹*/
        }
        if(top>0)                       /*如果棧不空*/
        {
            p=stack[--top];                 /*棧頂元素出棧*/
            printf("%2c",p->data);          /*訪問根結點*/
            p=p->rchild;                    /*遍歷右子樹*/
        }
    }
}

後序遍歷

void PostOrderTraverse2(BiTree T)
/*後序遍歷二叉樹的非遞迴實現*/
{
    BiTree stack[MaxSize];              /*定義一個棧,用於存放結點的指標*/
    int top;                            /*定義棧頂指標*/
    BitNode *p,*q;                      /*定義結點的指標*/
    top=0;                              /*初始化棧*/
    p=T,q=NULL;                         /*初始化結點的指標*/
    while(p!=NULL||top>0)
    {
        while(p!=NULL)                      /*如果p不空,訪問根結點,遍歷左子樹*/
        {
            stack[top++]=p;                 /*將p入棧*/
            p=p->lchild;                    /*遍歷左子樹*/
        }
        if(top>0)                           /*如果棧不空*/
        {
            p=stack[top-1];                     /*取棧頂元素*/
            if(p->rchild==NULL||p->rchild==q)   /*如果p沒有右孩子結點,或右孩子結點已經訪問過*/
            {
                printf("%2c",p->data);          /*訪問根結點*/
                q=p; 
                p=NULL; 
                top--;      
            }
            else
                p=p->rchild;
        }
    }
}

相關文章