線索二叉樹,或者說,對二叉樹線索化,實質上就是遍歷一棵二叉樹,在遍歷的過程當中,檢查當前結點的左、右指針域是否爲空。若是爲空,將它們改成指向前驅結點或後繼結點的線索。數據結構
當以二叉鏈表做爲存儲結構時,只能找到左右孩子信息,而不能直接獲得結點在任意序列中的前驅和後繼信息,這種信息只有在遍歷的動態過程當中才能獲得。 解決此問題最簡單的辦法是在每一個節點上增長兩個指針域fwd和bkwd,分別指示結點依任意次序遍歷時獲得前驅和後繼信息。顯然這樣作使得結構的存儲密度 大大下降,另外一方面,在有n個結點的二叉鏈表中一定存在n+1個空鏈域。由此設想可否利用這些空鏈域來存放前驅和後繼信息。ide
試作以下規定:若結點有左子樹,則其lchild域指向其左孩子,不然域指示其前驅,若結點有右子樹,則其rchild域指示其右孩子,不然令rchild指示其後繼。爲了不混淆,尚需改變結點結構,增長兩個標誌域。
lchild LTag data RTag rchild
其中:指針
LTag=0 lchild域指示結點的左孩子 LTag=1 lchild域指示結點的前驅 RTag=0 rchild域指示結點的右孩子 RTag=1 rchild域指示結點的後繼
以這種結點結構構成的二叉鏈表做爲二叉樹的存儲結構,叫作線索鏈表,其中指向結點前驅和後繼的指針,叫作線索。加上線索的二叉樹稱爲線索二叉樹。對二叉樹進行某種次序遍歷使其變爲線索二叉樹的過程叫作線索化。code
頭文件:it
/***************************************************************************************************** *Copyright: Yue Workstation * *FileName: IndexTree.h * *Function: 線索二叉樹數據結構定義 * *Author: Abel Lee * *CreateOn: 2012-2-19 * *Log: 2012-2-19 由Abel Lee建立 *****************************************************************************************************/ #ifndef INDEX_TREE_H #define INDEX_TREE_H #include "global.h" typedef enum{Link,Thread} PointerTag; //指針標誌 typedef int DataType; typedef struct BiThreTree { //定義結點元素 PointerTag LTag,RTag; DataType data; struct BiThreTree *lchild,*rchild; }BiThreTree; BiThreTree *pre; //全局變量,用於二叉樹的線索化 BiThreTree *CreateTree(void); void InThread(BiThreTree *T); BiThreTree *InOrderThrTree(BiThreTree *T); void InThrTravel(BiThreTree *Thre); #endif
源文件:io
/***************************************************************************************************** *Copyright:Yue Workstation * *FileName: IndexTree.c * *Function: 線索二叉樹操做 * *Author:Abel Lee * *CreateOn:2012-2-19 * *Log:2011-5-3 由Abel Lee建立 *****************************************************************************************************/ #include "../inc/IndexTree.h" /**************************************************************************************************** *Function Name: CreateTree * *Function: 按先序輸入創建二叉樹 * *Parameter: 無 * *Return Value:成功返回樹的指針,失敗返回NULL * *Author:Abel Lee * *Log:2012-2-19 ***************************************************************************************************/ BiThreTree *CreateTree(void) { BiThreTree *T; DataType e; scanf("%d",&e); if(e==0) { T=NULL; } else { T=(BiThreTree *)malloc(sizeof(BiThreTree)); T->data=e; T->LTag=Link; //初始化時指針標誌均爲Link T->RTag=Link; T->lchild=CreateTree(); T->rchild=CreateTree(); } return T; } /**************************************************************************************************** *Function Name: InThread * *Function: * *Parameter: 無 * *Return Value:成功返回樹的指針,失敗返回NULL * *Author:Abel Lee * *Log:2012-2-19 ***************************************************************************************************/ void InThread(BiThreTree *T) { BiThreTree *p; p=T; if(p) { InThread(p->lchild); if(!p->lchild) { p->LTag=Thread; p->lchild=pre; } if(!pre->rchild) { pre->RTag=Thread; pre->rchild=p; } pre=p; InThread(p->rchild); } } /**************************************************************************************************** *Function Name: InOrderThrTree * *Function: 中序線索化二叉樹 * *Parameter: T:二叉樹指針 * *Return Value:成功返回樹的指針,失敗返回NULL * *Author:Abel Lee * *Log:2012-2-19 ***************************************************************************************************/ BiThreTree *InOrderThrTree(BiThreTree *T) { BiThreTree *Thre; //Thre爲頭結點的指針 Thre=(BiThreTree *)malloc(sizeof(BiThreTree)); if(Thre == NULL) { perror("Thre == NULL,malloc error!\n"); return NULL; } Thre->lchild=T; Thre->rchild=Thre; pre=Thre; InThread(T); pre->RTag=Thread; pre->rchild=Thre; Thre->rchild=pre; return Thre; } /**************************************************************************************************** *Function Name: InThrTravel * *Function: 中序遍歷二叉樹 * *Parameter: Thre:二叉樹指針 * *Return Value:成功返回樹的指針,失敗返回NULL * *Author:Abel Lee * *Log:2012-2-19 ***************************************************************************************************/ void InThrTravel(BiThreTree *Thre) { BiThreTree *p; p=Thre->lchild; while(p!=Thre) //指針回指向頭結點時結束 { while(p->LTag==Link) p=p->lchild; printf("%4d",p->data); while(p->RTag==Thread&&p->rchild!=Thre) { p=p->rchild; printf("%4d",p->data); } p=p->rchild; } }