線索二叉樹(中序建立)
阿新 • • 發佈:2018-12-08
#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"); }