資料結構 第6章 樹之概念

2022-02-20 17:08:51 字數 3232 閱讀 6611

樹(tree)是 n(n>=0) 個結點的有限集。 n=0 時稱為空樹。在任意一棵非空樹中,有且僅有乙個特定的稱為的結點。當 n>1 時,其餘結點可分為 m (m>0) 個互不相交的有限集 t1、t2、……、tm。其中每乙個集合本身又是一棵樹,並且稱為根的子樹(subtree),如下圖所示:

其中根結點 a 有兩個子樹:

樹的結點包含乙個資料元素及若干指向其子樹的分支。結點擁有的的子樹數稱為結點的度。度為 0 的稱為葉結點或者終端結點;度不為 0 的結點稱為非終端結點或者分支結點。除根結點之外,分支結點也稱為內部結點。樹的度是樹內各結點的度的最大值。如下圖所示,因為這棵樹結點的度的最大值是結點 d 的度,為 3,所以樹的度也為 3 。

結點的子樹的根稱為該結點的孩子(child),相應地,該結點稱為孩子的雙親(parent) 。同乙個雙親的孩子之間互稱兄弟。結點的祖先是從根到該結點所經分支上的所有結點。所以對於 h 來說,d、b、a 都是它的祖先 。反之,以某結點為根的子樹中的任一結點都稱為該結點的子孫。b的子孫有 d、g、h、i,如下圖所示:

結點的層次(level)從根開始定義起,根為第一層,根的孩子為第二層,其雙親在同一層的結點互為堂兄弟。顯然下圖中的 d、e、f 是堂兄弟,而 g、h、丨、j 也是。樹中結點的最大層次稱為樹的深度(depth),當前樹的深度為4。

如果將樹中結點的各子樹看成從左至右是有次序的,不能互換的,則稱該樹為有序樹,否則稱為無序樹

相對於線性結構,樹的操作就完全不同了,這裡我們給出一些基本和常用操作。

我們這裡要介紹三種不同的表示法:雙親表示法孩子表示法孩子兄弟示法

我們假設以一組連續空間儲存樹的結點,同時在每個結點中,附設乙個指示器指示其雙親結點在鍊錶中的位置。也就是說,每個結點除了知道自己是誰以外,還知道它的雙親在**。它的結點結構為下圖所示:

其中 data 是資料域,儲存結點的資料資訊。而 parent 是指標域,儲存該結點的雙親在陣列中的下標。以下是我們的雙親表示法的結點結構定義**:

/* 樹的雙親表示法的結點結構定義 */

#define max_tree_size 100

typedef int elemtype; // 樹結點的資料型別

typedef struct ptnode //結點結構

ptnode;

typedef struct // 樹結構

; int r, n; // 根結點位置,結點數

}tree;

思路:由於根節點是沒有雙親的,所以我們約定根節點的指標域設定為 -1。這也意味著我們所有節點都存有它雙親的位置。樹結構和樹雙親表示法如下所示:

這樣的儲存結構,我們可以根據結點的 parent 指標很容易找到它的雙親結點,所用的時間複雜度為 〇(1),直到 parent 為 -1 時,表示找到了樹結點的根。

總結

優點:該儲存方式根據結點的 parent 指標很容易找到它的雙親結點,時間複雜度為 o(1)。

缺點:如果需要知道某個結點的所有孩子,需要遍歷整棵樹。

仔細觀察,我們為了要遍歷整棵樹,把每個結點放到乙個順序儲存結構的陣列中是合理的,但每個結點的孩子有多少是不確定的,所以我們再對每個結點的孩子建立乙個單鏈表體現它們的關係。

這就是我們要講的孩子表示法。具體辦法是,把每個結點的孩子結點排列起來, 以單鏈表作儲存結構,則 n 個結點有 n 個孩子鍊錶,如果是葉子結點則此單鏈表為空。然後 n 個頭指標又組成乙個線性表,採用順序儲存結構,存放進乙個一維陣列中,如下圖所示:

為此,設計兩種結點結構,乙個是孩子鍊錶的孩子結點,如下圖所示。

其中 data 是資料域,儲存某結點的資料資訊。firstchild 是頭指標域,儲存該結點的孩子鍊錶的頭指標。

以下是我們的孩子表示法的結構定義**:

/* 樹的孩子表示法結構定義 */

#define max_tree_size 100

typedef int telemtype;

typedef struct ctnode //子結點結構

ctnode, *childptr;

typedef struct //表頭結構

ctchain;

typedef struct //樹結構

; int r, n; //根結點位置,結點數

}tree;

總結缺點: 如果需要知道某個結點的雙親,需要遍歷整棵樹

改進:孩子兄弟表示法

剛才我們分別從雙親的角度和從孩子的角度研究樹的儲存結構,如果我們從樹結點的兄弟的角度又會如何呢?當然,對於樹這樣的層級結構來說,只研究結點的兄弟是不行的,我們觀察後發現,任意一棵樹,它的結點的第乙個孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。因此,我們設定兩個指標,分別指向該結點的第乙個孩子和此結點的右兄弟。

結點結構如下圖所示:

其中 data 是資料域,firstchild 為指標域,儲存該結點的第乙個孩子結點的儲存位址,rightsib 是指標域,儲存該結點的右兄弟結點的儲存位址。

孩子兄弟表示法的結構定義**如下:

/* 樹的孩子兄弟表示法結構定義 */

typedef struct csnode

csnode, *cstree;

這種方法實現的示意圖如下圖所示。

這種表示法,給查詢某個結點的某個孩子帶來了方便,只需要通過 fistchild 找到此結點的長子,然後再通過長子結點的 rightsib 找到它的二弟,接著一直下去,直到找到具體的孩子。當然,如果想找某個結點的雙親,完全可以再增加乙個 parent 指標域來解決快速查詢雙親的問題,這裡就不再細談了。

總結

優點:可以把一棵複雜的樹變成一棵二叉樹,這樣就可以充分利用二叉樹的特性和演算法來處理這棵樹了。

參考:

《大話資料結構 - 第6章》 樹

第6章核心資料結構之資料結構以及選擇

6.5 資料結構以及選擇 linux中最重要的資料結構 鍊錶 佇列 紅黑樹。如何在 中具體選擇使用哪種資料結構。如果對資料集合的主要操作是遍歷資料,就使用鍊錶。事實上沒有資料結構可以提供比線性演算法複雜度更好的演算法遍歷元素,應該用最簡單的資料結構完成簡單工作。當效能並非首要考慮因素時,或者當需要儲...

資料結構 第1章 基本概念

1.演算法描述 演算法是一組完成特定任務的有窮指令序列。所有的演算法都必須有 輸入,輸出,確定性,有限性和有效性。2.選擇排序 selection sort 原理 首先在排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到排序列未尾。依此類推,直到所...

第9章 資料結構

第9章 資料結構 my frames,button my sub of 日誌查詢 push button2 溫金簡訊查詢 push button3 中均簡訊查詢 push button4 機器資訊查詢 push button5,ip資訊查詢 push button6,裝置資訊維護 push butt...