線索二叉樹和中序非遞迴遍歷線索化後的二叉樹
阿新 • • 發佈:2018-12-25
//線索二叉樹 #include<stdio.h> #include<malloc.h> #include<process.h> #define OVERFLOW -2 //二叉樹的二叉線索儲存結構 enum PointerTag{Link,Thread}; //列舉型別,Link(0):指標,Thread(1):線索 struct BiThrNode { char data; BiThrNode *lchild,*rchild;//左右孩子指標 PointerTag LTag,RTag;//左右標誌 }; typedef BiThrNode *BiThrTree; //按照先序的次序輸入二叉樹中節點的值,構造線索二叉樹T,char,空格表示空節點 void CreateBiThrTree( BiThrTree &T) { char ch; scanf("%c",&ch); if(ch == ' ') T=NULL; else { T=(BiThrTree)malloc(sizeof(BiThrNode));//生成根節點,先序 if(!T) exit(OVERFLOW); T->data=ch;//給根節點賦值 CreateBiThrTree(T->lchild);//遞迴構造左子樹 if(T->lchild)//如果有左孩子 T->LTag=Link;//給座標值賦值為0 CreateBiThrTree(T->rchild);//遞迴構造右子樹 if(T->rchild) T->RTag=Link;//如果有右孩子,就給右標誌賦值為0 } } BiThrTree pre;//全域性變數,始終指向剛剛訪問過的節點 //通過中序遍歷進行中序線索化,線索化之後,pre指向最後一個節點 void InThreading(BiThrTree p)//p為指向根節點的指標 { if(p)//線索二叉樹不空 { InThreading(p->lchild);//遞迴左子樹線索化 if(!p->lchild)//左子樹為空 { p->LTag=Thread;//左標誌為線索 p->lchild=pre;//左孩子指標指向前驅 } if(!pre->rchild)//如果前驅沒有右孩子 { pre->RTag=Thread;//前驅的右孩子為線索 pre->rchild=p;//前驅的右孩子節點指向其後繼節點,(即當前節點p) } pre=p;//保持pre指向p的前驅 InThreading(p->rchild);//遞迴右子樹線索化 } } //中序遍歷二叉樹T,將其中序線索化,Thrt指向頭結點 void InOrderThreading(BiThrTree &Thrt,BiThrTree T) { Thrt=(BiThrTree)malloc(sizeof(BiThrNode));//生成頭結點 if(!Thrt) exit(OVERFLOW); Thrt->LTag=Link;//建立頭結點左標誌為指標 Thrt->RTag=Thread;//右標誌為線索 Thrt->lchild=Thrt;//右指標回指 if(!T)//如果二叉樹空則左指標回指 Thrt->lchild=Thrt; else { Thrt->lchild=T;//頭指標的左指標指向根節點 pre=Thrt;//pre的初值指向頭結點 InThreading(T);//中序遍歷,進行中序線索化,pre指向中序遍歷後的最後一個節點 //收尾工作 pre->RTag=Thread;//最後一個節點的右標誌為線索 pre->rchild=Thrt;//最後一個節點的右指標指向頭結點 Thrt->rchild=pre;//頭節點的右指標指向中序遍歷的最後一個節點 } } //中序遍歷線索化後的二叉樹T(頭節點)的非遞迴演算法 void InOrderTraverse_Thr(BiThrTree T) { BiThrTree p; p=T->lchild;//p指向根節點 while(p != T) //空樹或者是遍歷結束時,p==T { while(p->LTag == Link)//由根節點一直找到二叉樹的最左節點 p=p->lchild; printf("%c ",p->data);//訪問此節點 while(p->RTag == Thread && p->rchild != T)//p->rchild是後繼,且不是遍歷的最後一個節點 { p=p->rchild; printf("%c ",p->data);//訪問後繼節點 } p=p->rchild;//若p->rchild不是線索,p指向右孩子,返回迴圈,找這棵子樹中序遍歷的第一個節點 } } void main() { BiThrTree H,T; printf("請按照先序的次序輸入二叉樹:\n"); CreateBiThrTree(T);//按照先序產生二叉樹 InOrderThreading(H,T);//H是頭,T是根,中序遍歷的過程中,中序線索化二叉樹 printf("中序遍歷線索二叉樹:"); InOrderTraverse_Thr(H); printf("\n"); }
程式的執行結果:
以下圖片能夠幫助你更好地理解本程式:
圖一 空的二叉樹
圖二 二叉樹的二叉線索儲存結構
圖三 CreateBiThrTree()產生的二叉樹
圖四 中序線索二叉樹儲存結構
圖 5
中序線索化二叉樹