標籤:
線索二叉樹,在原始二叉樹的基礎上對節點進行“擴容”,使之變成了一顆節點資訊更加豐富,利用率更高的二叉樹。具體來說增加了兩個指示標籤,ltag和rtag,每個標籤有兩個值,1和0,0代表存在孩子,指標指向相應孩子,1代表沒有對應的孩子,指標表示線索,指向其前驅或後繼。這樣雖然節點多佔用了空間(其實很少,只是兩個枚舉常量而已),換來的卻是讓原來結構中存在的大量null 指標利用起來,變成線索,指示前驅後繼,從而使得空間利用效率大大提高, 並且有了線索以後,對後續的尋找等操作提高很多效率。
下面是代碼,本來以為只需要修改一下標籤就完事的,結果寫起來還要考慮許多問題:1,pre指標(指向前一個節點的全域指標),以及它的初始化。2,二叉樹建立時仍然採用前序方式,但是對節點線索化時需要用中序遍曆,最後遍曆列印時,因為有了標籤,所以可以採用迭代的方式列印輸出,至於可否用遞迴方式列印,還沒有嘗試過。
下面是代碼,主要思路:前序方式建立二叉樹(令其標籤預設初始化為link),線索化,pre指標的初始化,利用迭代中序遍曆列印二叉樹。
痛點是後面兩個,直接想可能很難寫出來,可以參照書本畫個圖理解一下,二叉樹這部分畫圖理解還是蠻重要的!
#include<iostream>using namespace std;enum Tag{link,thread}; //這裡定義一個枚舉類型,link(0)表示指向孩子,thread(1)表示指向前驅後繼的線索//定義節點結構typedef struct BiThreadNode{ char data; struct BiThreadNode *lchild,*rchild; Tag ltag,rtag;}BiThreadNode,*BiThreadTree;//定義一個全域變數,始終指向剛剛訪問過的節點BiThreadTree pre;//前序走訪建立二叉樹void createBtTree (BiThreadTree &T){ char c; cin>>c; if(c==‘#‘) { T=NULL; } else { T=new BiThreadNode; T->data=c; T->ltag=T->rtag=link; createBtTree(T->lchild); createBtTree(T->rchild); }}//中序遍曆二叉線索樹並且對節點進行處理.void midOrderThread(BiThreadTree &T){ if(T) { midOrderThread(T->lchild);//對節點進行處理,即把判斷為線索的指標域修改為thread。注意修改前驅後繼時分別對pre和T兩個指標指向的節點進行處理。 if(!T->lchild) { T->ltag=thread; T->lchild=pre; //當發現左孩子為空白時另ltag=thread,同時讓lchild指標(本來為空白)指向前驅節點pre } if(!pre->rchild) { T->rtag=thread; //當發現pre節點的右孩子為空白時,另其rtag=thread,同時讓他的rchild指向其後繼節點T pre->rchild=T; } pre=T; midOrderThread(T->rchild); }}//由於以上只是處理了動態過程的代碼,初始化時會因為pre指標沒有賦值從而出錯,需要在建立個函數解決此問題//建立頭結點,並中序線索二叉樹void inOrderThread(BiThreadTree &p,BiThreadTree &t){ p=new BiThreadNode; p->ltag=link; p->rtag=thread; p->rchild=p; if(!t) { p->lchild=p; p->ltag=link; } else { p->lchild=t; pre=p; midOrderThread(t); pre->rchild=p; pre->rtag=thread; p->rchild=pre; }}//非遞迴方式遍曆二叉樹並輸出void inOrderVisit(BiThreadTree p){ BiThreadTree T; p->lchild=T; while(T!=p) { while(T->ltag==link) { T=T->lchild; } cout<<T->data; while(T->rtag==thread&&T->rchild!=p) { T=T->rchild; cout<<T->data; } T=T->rchild; }}int main(){ BiThreadTree Tree,p; createBtTree(Tree); inOrderThread(p,Tree); inOrderVisit(p);}
一步一步寫資料結構(線索二叉樹)