數據結構之線索7—二叉樹和森林

線索二叉樹node

利用空指針域來真存放結點的前驅和後繼信息算法

♦ 定義:  數組

  • 前驅與後繼:在二叉樹的先序、中序或後序遍歷序列中兩個相鄰的結點互稱爲~
  • 線索:指向前驅或後繼結點的指針稱爲~
  • 線索二叉樹:加上線索的二叉鏈表表示的二叉樹叫~
  • 線索化:對二叉樹按某種遍歷次序使其變爲線索二叉樹的過程叫~

♦ 實現:spa

  • 在有n個結點的二叉鏈表中一定有n+1個空鏈域
  • 在線索二叉樹的結點中增長兩個標誌域(0指結點,1左前右後)
  1.  ltag :若 ltag=0, lchild 域指向左孩子;
  2. 若 ltar=1, lchild域指向其前驅
  3. rtag :若 rtag =0, rchild 域指向右孩子;
  4. 若 rtag=1, rchild域指向其後繼

 

 

例如:遍歷中序線索二叉樹3d

在中序線索二叉樹中找結點後繼的方法:指針

(1)若rtag=1, 則rchild域直接指向其後繼code

(2)若rtag=0, 則結點的後繼應是其右子樹的左鏈尾(ltag=1)的結點blog

在中序線索二叉樹中找結點前驅的方法:io

(1)若ltag=1, 則lchild域直接指向其前驅class

(2)若ltag=0, 則結點的前驅應是其左子樹的右鏈尾(rtag=1)的結點

 

樹和森林

樹的存儲結構有:雙親表示法、孩子表示法、孩子兄弟表示法。

1.雙親存儲表示法

用一組地址連續的存儲單元來存放樹的結點,每一個結點有兩個域:  

data域-----存放結點的信息;    

parent域-----存放該結點惟一的雙親結點的位置(數組下標)

雙親表示法的存儲結構描述爲:

#define MaxTreeSize 100  typedef char DataType; typedef struct{ DataType data; int parent; } PTreeNode; typedef struct {  PTreeNode nodes[MaxTreeSize]; int r,n;//根結點的位置和結點個數 
 }PTree; PTree T;

 

二、孩子表示法

 把每一個結點的孩子結點排列起來,看做線性表,且以單鏈表作存儲結構。

孩子表示法的存儲結構描述爲:

typedef struct Cnode {   int child;   struct CNode *next; } Cnode; /*孩子結點類型說明*/ typedef struct {  DataType data; Cnode *firstchild; } PTNode; /*數組的每一個元素的類型說明*/ typedef struct { PTNode nodes[MaxTreeSize]; int n,root; } Ctree;

 

三、孩子兄弟表示法

 用二叉鏈表做爲樹的存儲結構,每一個結點的左鏈域指向該結點的第一個孩子,右鏈域指向下一個兄弟結點。因爲結點中的兩個指針指示的分別爲「孩子」和「兄弟」,故稱爲「孩子-兄弟鏈表」。(左孩右兄)

樹的孩子兄弟鏈表的存儲結構描述爲:

typedef struct CSNode{ ElemType data; struct CSNode *firstchild,*nextsibling; } CSNode, *CSTree;

 

孩子兄弟存儲結構的優勢能夠方便地實現樹和二叉樹的相互轉換和樹的各類操做;

缺點查找當前結點的雙親結點比較麻煩。 解決方法:增設parent域。

 

森林轉換成二叉樹

轉換原則:

(1)將森林中的每棵樹轉換成等價的二叉樹;

(2)保留第一棵二叉樹,從第二棵二叉樹開始,依次將後一棵二叉樹的根結點做爲前一棵二叉樹根結點的右孩子,全部二叉樹依此相連。

 

 

樹轉化爲二叉樹的意義

一、由於對二叉樹的許多操做算法簡單,而任何樹均可以與二叉樹相互轉換,這樣就解決了樹的存儲結構及其運算中存在的複雜性。

二、全部的樹中,2度樹的鏈域(存儲空間)利用率最高。

 

樹和森林的遍歷

1.樹的遍歷

所謂樹的遍歷,就是按照某種順序依次訪問樹中各個結點,並使得每一個結點只被訪問一次。也就是把非線性結構的樹結點變成線性序列的一種方式。

樹的遍歷方法有:

按廣度優先遍歷(即按層次遍歷)

按深度優先遍歷,又可分爲:前序遍歷和後序遍歷

 

2.森林的遍歷

森林的遍歷可分爲前序遍歷中序遍歷

相關文章
相關標籤/搜索