數據結構(32)樹、森林

目錄

1、樹的存儲結構

1.1、雙親表示法

1.2、孩子表示法

1.3、孩子兄弟表示法

2、樹、森林與二叉樹的轉換

3、樹和森林的遍歷


1、樹的存儲結構

樹的存儲方式有很多,即可採用順序存儲結構,又可採用鏈式存儲結構,但無論採用何種存儲方式,都要求能唯一地反映樹中各結點之間的邏輯關係,這裏介紹3中常用的存儲結構。

1.1、雙親表示法

這種存儲方式採用一組連續空間來存儲各個結點,同時在每個結點中增設一個僞指針,指示其雙親結點在數組中的位置。如圖32-1所示,根節點下標爲0,其僞指針域爲-1。

                                      圖32-1  樹的雙親表示法

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

#define MAX_TREE_SIZE 100  //樹中最多結點數
typedef struct
{
    ElemType data;   
    int parent;
}PTNode;
typedef struct
{
    PTNode nodes[MAX_TREE_SIZE];  //雙親表示
    int n;  //結點數
}

該存儲結構利用了每個結點(除根節點外)只有唯一雙親的性質,可以很快得到每個結點的雙親結點,但求結點的孩子時需要遍歷整個結構。

注意:區別樹的順序存儲結構與二叉樹的順序存儲結構。在樹的順序存儲結構中,數組下標代表結點編號,下標中所存的內容指示了結點之間的關係。而在二叉樹的順序存儲結構中,數組下標既代表了結點的編號,又指示了二叉樹中各節點的關係哦。當然,二叉樹屬於樹,因此二叉樹都可以用樹的存儲結構來存儲,但樹卻不能用二叉樹的存儲結構來存儲。

1.2、孩子表示法

孩子表示法是將每個結點的孩子結點都用單鏈表連接起來形成一個線性結構,此時n個結點就有n個孩子鏈表(葉子結點孩子鏈表爲空表)。

這種存儲方式尋找子女的操作非常直接,而尋找雙親的操作需要遍歷n個孩子鏈表。

1.3、孩子兄弟表示法

 孩子兄弟表示法又稱爲二叉樹表示法,即以二叉鏈表作爲樹的存儲結構。孩子兄弟表示法使得每個結點包括三部分內容:結點值、指向結點第一個孩子結點的指針 ,以及指向結點下一個兄弟結點的指針(沿着此域可以找到結點的所有兄弟結點),如圖32-2(b)所示。

                                                圖32-2  樹的孩子表示法和孩子兄弟表示法

2、樹、森林與二叉樹的轉換

由於二叉樹和樹都可以用二叉鏈表作爲存儲結構,因此以二叉鏈表作爲媒介可以導出樹與二叉樹的一個對應關係,即給定一棵樹,可以找到唯一的一棵二叉樹與之對應。從物理結構上看,他們的二叉鏈表是相同的,只是解釋不同而已。

樹轉換爲二叉樹的規則:每個結點左指針指向它的第一個孩子,右指針指向它在樹中的相鄰右兄弟,這個規則又稱“左孩子右兄弟”。由於根節點沒有兄弟,所以對應的二叉樹沒有右子樹。如圖32-3所示。

                                            圖32-3  樹和二叉樹的對應關係

樹轉換爲二叉樹的畫法:①在兄弟結點之間加一連線;②對每個結點,值保留它與第一個孩子的連線,而與其他孩子的連線全部抹掉;③以數根爲軸心,順時針旋轉45°。

將森林轉換爲二叉樹的規則與樹類似,先將森林中的每棵樹轉換爲二叉樹,由於任何一棵和樹對應的二叉樹的右子樹爲空,若把森林中第二棵樹根視爲第一棵樹根的右兄弟,即將第二棵樹對應的二叉樹當做第一棵二叉樹跟的右子樹,以次類推,就可以將森林轉換爲二叉樹。

森林轉換爲二叉樹的畫法:①將森林中的每棵樹轉換成相應的二叉樹;②每棵樹的根也可視爲兄弟關係,在每棵樹的根之間加一根連線;③以第一棵樹的根爲軸心順時針旋轉45°。

二叉樹轉換爲森林的規則:若二叉樹非空,則二叉樹的根及其左子樹爲第一棵樹的二叉樹形式,二叉樹根的右子樹又可視爲一個由除第一棵樹外的森林轉換後的二叉樹,以此類推,知道只剩一顆沒有右子樹的二叉樹爲止,最後再將每棵二叉樹一次轉換爲樹,就得到了遠森林,如圖32-4所示。二叉樹轉換爲樹或森林是唯一的。

                                                   圖32-4  森林與二叉樹的對應關係

二叉樹轉換爲樹就是樹轉換爲二叉樹的逆運算,因爲兩者一一對應。

二叉樹轉換爲樹:①以樹根爲軸心,逆時針旋轉45°。②恢復每個結點與其父結點的連線(同一深度沒有爸爸只有兄弟的以最左邊的兄弟爲準,找到爸爸)。③兄弟之間的連線去掉。

3、樹和森林的遍歷

樹的遍歷是指用某種方式來訪問樹中的每個結點,且僅訪問一次,主要有兩種方式:

1)先根遍歷。若樹非空,先訪問根節點,再依次遍歷根節點的每棵子樹。遍歷子樹時仍遵循先根後子樹的原則。其遍歷序列與這棵樹對應的二叉樹的先序序列相同。

2)後根遍歷。若樹非空,先依次遍歷根節點的每棵子樹,再訪問根節點。遍歷子樹時仍遵循先子樹後根的規則,其遍歷序列與這棵樹相應的中序序列相同。

圖32-3所示的樹的先根遍歷序列爲ABEFCDG,後根遍歷序列爲EFBCGDA(對應二叉樹的中序遍歷)。

根據森林和樹相互遞歸的定義,可得到森林的兩種遍歷方法。

1)先序遍歷森林。若森林非空,則:

①訪問森林中第一棵樹的根節點。

②先序遍歷第一棵樹的根節點的子樹森林。

③先序遍歷除去第一棵樹之外其餘的樹組成的森林。

2)中序遍歷森林。若森林非空,則:

①中序遍歷第一棵樹的根節點的子樹森林。

②訪問森林中第一棵樹的根節點。

③中序遍歷除去第一棵樹之外其餘的樹組成的森林。

圖32-4所示的森林先序遍歷序列爲:ABCDEFGHI;中序遍歷的序列爲:BCDAFEHIJ。

當森林轉換爲二叉樹時,其第一棵樹的子樹森林轉換爲左子樹,剩餘數的森林轉換爲右子樹,可知森林的先序和中序即爲其對應二叉樹的先序和中序遍歷。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章