資料結構-練習6 線索二叉樹的建立和遍曆

來源:互聯網
上載者:User

   前面一篇部落格講述了二叉樹的建立和遍曆,無論是前序還是中序或是後序,只不過是訪問資料的順序不一樣,是為了訪問二叉樹而人為化的一種鏈式“形”,突出的是訪問的內在聯絡。同樣地,線索化的二叉樹也是,在前驅和後繼之間建立起一種聯絡,從而使訪問特別快,特別方便。

 

    線索化二叉樹是在二叉樹的序(前,中,後)的基礎上建立起來的。其關鍵是利用閒置lchild和rchild儲存其前驅和後繼,對於度為2 的節點,lchild和rchild!=null,已經儲存了相關資訊。所以線索化二叉樹時,就是找出lchild和rchild(==null)的節點,然後使lchild和rchild分別指向前驅和後繼。為了遍曆線索化二叉樹時,我們能有效區分lchild(rchild)是儲存了左子樹(右子樹)還是儲存了前驅(後繼),我們可以增加兩個有效標誌位lfag,rflag。具體原理見如下:

                                                                                                                  

                                                                                                                                  

                                                                                  

 

 

 

 

 

   仿造普通的”線索“的表示,箭頭線段分別表示,前驅和後繼,注意:箭頭線段的節點沒有左子樹(右子樹)。

    採用的節點資料結構:

                                           

typedef struct Tnode{ char data; Tnode* lchild; Tnode* rchild; bool lflag; bool rflag;}

我採用前序建立二叉樹,前序走訪,中序線索化二叉樹,然後線索遍曆二叉樹,共四個函數。

 

代碼如下:

 

        

#include<iostream>using namespace std;typedef struct Tnode{ char data; Tnode* lchild; Tnode* rchild; bool lflag; bool rflag;} BiTnode,* BiTree;//前序建立二叉樹void CreateBiTree(BiTree* T){ char inputChar; cin>>inputChar; //空子樹 if(inputChar=='#')  {  *T=0;  return ;    } else {    (*T)=(BiTree)malloc(sizeof(BiTnode)); if(!(*T)) throw "Invalid Address"; else { (*T)->data=inputChar; (*T)->lflag=0; (*T)->rflag=0; CreateBiTree(&((*T)->lchild)); CreateBiTree(&((*T)->rchild)); } }}//前序走訪二叉樹void preTraverse(BiTree T){ if(T) { cout<<T->data<<","; preTraverse(T->lchild); preTraverse(T->rchild); }}//中序二叉樹線索化void inThreadedBiTree(BiTree T,BiTree * h ){  if(T!=NULL)  {  inThreadedBiTree(T->lchild,h);  if(T->lchild==NULL)  {  T->lchild=*h;  T->lflag=1;    }  if(*h!=NULL&&((*h)->rchild==NULL))  {  (*h)->rchild=T;  (*h)->rflag=1;    }  *h=T;//採用二級指標的意義就在於此,為了指向T,T一級指標,這樣可以省空間  inThreadedBiTree(T->rchild,h);    }}//線索遍曆二叉樹void inThreadTraverse(BiTree T){  BiTree h;  if(T==NULL)return;  h=T;  while(h->lflag==0)h=h->lchild;  cout<<h->data<<",";  while(h->rchild!=NULL)  {  if(h->rflag==1)  h=h->rchild;  else  {  h=h->rchild;  while((h->lflag==0)&&(h->lchild!=NULL))  h=h->lchild;  }  cout<<h->data<<",";  }}int main(){BiTree* T=(BiTree*)malloc(sizeof(BiTree*));;    CreateBiTree(T);cout<<"前序輸出二叉樹:"<<endl;    preTraverse(*T);BiTree h=NULL;    inThreadedBiTree( *T, &h );    cout<<endl<<"線索遍曆:";inThreadTraverse(*T);        return 0; }

註:其他方法(前序線索和後序線索)類似,明白原理即可,要用再查書。可見線索化二叉樹,只是引入了一種遍曆的方式而已,其帶來的劣勢是:增加了空間。

 

測試結果:按開始給出的:輸入 ABC###DE##F##

 

                                                                                                 

 

          分兩種情況,rchild!=null,即不存在右子樹的,按後繼鏈尋找,反之,按原遍曆順序尋找,直到末尾點,讀者可按運行結果筆畫一下。

 

                           

 

 

 

 

  

  

    

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.