1. 程式人生 > >線索二叉樹(中序建立)

線索二叉樹(中序建立)

#include"stdio.h"
#include"string.h"
//這裡表示一個結點
typedef struct NODE{
    char node;
    struct NODE *nextleft;
    struct NODE *nextright;
    int ltop;
    int rtop;
}BiTNode,*BiTree;

//用前序遍歷建立一個樹
CreatBiTree(BiTree *T){
   char c;
   scanf("%c",&c);
   if(c==' ')
      *T=NULL;
   else{
    *T=(BiTNode *)malloc(sizeof(BiTNode));
    (*T)->node=c;
    (*T)->ltop=1;
    (*T)->rtop=1;
    CreatBiTree(&(*T)->nextleft);
    CreatBiTree(&(*T)->nextright);
   }
}
//前置結點 一開始指向根結點
BiTNode *pre;
//利用中序列表遍歷並建立線索樹
InOrderTraverse(BiTNode *T){
     if(T!=NULL){
        //向左邊的子樹遞迴
         InOrderTraverse(T->nextleft);
       //上面一個遞迴結束之時,應是已到達了最左邊的子樹,且pre為最左邊的子樹的前置結點

         if(T->nextleft==NULL){
            T->ltop=0;
            T->nextleft=pre;//因為T->nextleft為NULL。所以將T->nextleft指向前置

         }
         //然後前置結點的後置應該為T。所以判斷一下前置結點的右結點是否為NULL。看能否指向後置,還是已經指向了右子樹
         if(pre->nextright==NULL){
            pre->rtop=0;
            pre->nextright=T;
         }
         //將前置的結點更新
         pre=T;
         InOrderTraverse(T->nextright);
     }
    }
visit(char node){
     printf("%c",node);
    }
//中序遍歷二叉樹 非遞迴
InOrderTraversecheck(BiTNode *T){
    BiTNode *p;
    p=T->nextleft;
    while(p!=T){
        //利用迴圈,使p->nextleft為前置,不為子樹。這樣會使之指向最左邊的子樹
        while(p->ltop==1){
            p=p->nextleft;
        }
       //訪問最左邊的子樹
        visit(p->node);
        //如果最左邊的子樹沒有右子樹。並且p->nextright不指向頭指標。則使p回到上一層,即指向p的後置結點
        while(p->rtop==0&&p->nextright!=T){
            p=p->nextright;
            //訪問此結點
            visit(p->node);
        }
        //並使之更新。指向的他的右邊結點(這個更新未區分是子樹還是後置)
        p=p->nextright;
    }
    }
//這個函式的意義是建立一個頭指標指向根結點
InOrderThreading(BiTree *p,BiTree T){
    (*p)=(BiTree)malloc(sizeof(BiTNode));
    (*p)->nextright=(*p);
    (*p)->rtop=0;
    (*p)->ltop=1;
    if(T==NULL){
        (*p)->nextleft=(*p);
        (*p)->ltop=0;
    }
    else{
        (*p)->nextleft=T;
         pre=(*p);
         InOrderTraverse(T);
         pre->rtop=0;
         pre->nextright=(*p);
         (*p)->nextright=pre;
    }
   }
//訪問到此結點,現在對此結點進行操作
visit1(BiTNode *T,int level){
    printf("%c是二叉樹中的第%d層資料\n",T->node,level);
}
//中序遍歷一顆二叉樹
PerOrderTraverse(BiTNode *T,int level){
    if(T!=NULL){

         PerOrderTraverse(T->nextleft,level+1);
         visit1(T,level);
         PerOrderTraverse(T->nextright,level+1);
    }
}
int main()
{  int level=1;
    BiTree T,p;
    CreatBiTree(&T);
    printf("這裡是用普通的遞迴遍歷二叉樹:\n");
    PerOrderTraverse(T,level);
    InOrderThreading(&p,T);
    printf("這裡是用迴圈遍歷二叉樹:\n");
    InOrderTraversecheck(p);
    printf("\n");

}