1. 程式人生 > >數據結構學習之第7章 樹和二叉樹

數據結構學習之第7章 樹和二叉樹

順序 兩層 遍歷二叉樹 data 等價 樹的高度 高度 問題 truct

數據結構學習之第7章 樹和二叉樹

0x7.1.1 樹的基本概念

?1.樹的定義

? 樹是由n(n>=0)個結點(或元素)組成的有限集合(記為T)

? 如果n>0,這n個結點中有且僅有一個結點作為樹的根結點,簡稱為根,其余結點可分為m(m>=0)個互不相交的有限集\[T_{1}T_{2}\cdots T_{m}\],其中每個子集又是一棵符合定義的子樹,稱為根結點的子樹。

知識點:由樹的定義我們可以看出來樹的結構是遞歸的

?2.樹的邏輯表示法

? 1.樹形表示法

? 2.文氏圖表示法

? 3.凹入表示法*

? 4.括號表示法

0x7.1.2 樹的基本術語

? 1.結點的度與樹的度:

? 樹中某個子結點的個數稱為該結點的度

,樹中所有結點的度中最大值稱為樹的度,我們通常稱樹的度為m的樹稱為m次數。

? 2.分支結點與葉子結點:

? 樹中度不為0的結點稱之為非終端結點,分支結點,根據度的數目分為單分支、雙分支、多分枝

? 3.路徑與路徑長度:

? 路徑從i->j經過的點序列 \[k_{i}k_{i+1} \cdots k_{j} \]

? 路徑長度=路徑上的分支數=點數-1

? 4.孩子結點、雙親結點、兄弟結點

? 孩子結點: 每個結點的後繼結點

? 兄弟結點: 具有同一雙親結點的孩子結點

? 5.結點層次和樹的高度

? 跟結點開始算第一層,根結點的孩子結點算第二層,結點層次也可稱為結點深度

? 樹中最大的結點層次稱為樹的高度。

? 6.有序樹和無序樹

? 有序樹: 各結點的子樹按照一定次序從左到右排序

? 默認一般為有序樹

? 7.森林

? n(n>0)互不相交的子樹的集合稱為森林

0x7.1.3 樹的性質

性質1: 樹中的結點數目等於所有結點的度數和+1

證明: 每個結點有且僅有一個前驅節點,這樣結點與指向它的分支一一對應,也就是一個分支對應的一個結點,這樣除開跟結點就有 分支數目等於結點數目,加上根結點就是, 所有結點的度數和+1 = 結點數目(缺少一度取指向根結點)

性質2: 對於度為m的樹第i層的結點數最多為為\[m^{i-1}\]

證1: 歸納法

i=0 -> 1 正確

假設i-1層 為 \[m^{i-2}\]

個結點

有樹的度的定義可知,每個結點的孩子結點為m,由此可得 i 層 為 \[m^{i-1}\]

性質3: 高度為h的m次樹最多有\[\frac{m^h-1}{m-1}\]個結點

有性質2易得

\[m^{0}+m^{1} \cdots + m^{h-1} = \frac {m^{h}-1}{m-1} \]

由此可知滿m次數的定義為: 滿足性質3的時候是滿m次數

性質4: 具有n個結點的m次樹的最小高度為: \[log_m{(n(m-1)+1)}\]

例子: 3次數 n=20 -> \[\lceil log_3{41} \rceil\] = 4

最大高度的話: n-m+1

直線的話: n個點->n高度

常用的計算技巧:

結點的度數之和= \[n_{0}+n_{1}+2n_{2}+ \cdots + mn_{m}\] = n-

\[n_{0}+n_{1}+n_{2}+ \cdots + n_{m}\] = n

0x7.1.4 樹的基本運算

?樹的遍歷:

1.先根遍歷

? (1)訪問根結點

? (2)按照從左到右的順序依次先根遍歷根結點的每一棵子樹。(遞歸定義)

2.後根遍歷

? (1)按照從左到右的順序依次先根遍歷根結點的每一棵子樹

? (2)訪問根結點

3.層次遍歷

? 從根結點開始從上到下、從左到右的次序訪問樹中的每一個結點。

7.1.5 樹的存儲結構

1.雙親存儲結構

typedef struct
{
    ElemType data;
    int parent; //順序存儲
}PTree[MaxSize]; 

2.孩子鏈結構

typedef struct node
{
    ElemType data;
  struct node * sons[MaxSons];
}TSonNode;

3.孩子兄弟鏈

typedef struct node
{
  ElemType data;
  struct node * vp; //孩子結點
  struct node * bp; //兄弟結點
}TSBNode;

0x7.2 二叉樹的概念和性質

7.2.1 二叉樹的定義和樹區別

? 1.二叉樹是一個有限的結點集合,這個集合或者為空,或者由一個根結點和兩棵互不相交的稱為左子樹和右子樹的二叉樹組成。

? 2.樹與二叉樹的區別

? (1) 度為2的樹中至少有一個結點的度為2,而二叉樹沒有這種要求。

? (2)二叉樹嚴格區分左右子樹

? 3.滿二叉樹的定義

? (1)一棵二叉樹中,如果所有分支結點都有左孩子結點和右孩子結點,並且所有葉子結點都集中在二叉樹的最下一層。

? (2)高度為h且二叉樹最下一層的結點數為\[2^{h-1}\]

? 4.非空滿二叉樹的特點:

? (1)度為0或者度為2

? (2)葉子結點都在最下一層

? 5.完全二叉樹的定義

? 二叉樹中只有最下面兩層的結點的度數可以小於2,並且最下面一層的葉子結點都依次排列在該層最左邊的位置上。

? 6.非空完全二叉樹的特點

>葉子結點只可能在最下面兩層中出現
>
>對於最大層次中的葉子結點,都依次排列在左邊
>
>如果有度為1的結點只可能有一個,且該結點只有左孩子
>
>按層序編號時,一旦出現編號i的結點是葉子結點或只有左孩子結點的,則編號大於i的結點均為葉子結點
>
>當結點總數n為奇數時,$$n_{1}$$=1,當為偶數時,$$n_{1}$$=0
0x7.2.2 二叉樹的性質

性質1:

非空二叉樹上葉子結點數等於雙分支結點數目+1

證明: n=n0 + n1 + n2 = n1 + 2*n2 +1 => n0 = n2+1

總結下常用等式:

\[n = n_{0}+n_{1}+n_{2}=2n_{2}+n_{1}+1=所有結點的度+1\]

所有結點的度數之和 = \[2n_{2} + n_{1}\]

性質2: 非空二叉樹的第i層上最多有\[2^{i-1}\]個結點。-> \[m^{i-1}\]

性質3: 高度為h的二叉樹最多有 \[2^{h}-1\]個結點

性質4:

完全二叉樹中層序編號為i的結點 若 i \[\leq \lfloor n/2 \rfloor \]\[2i \leq n\] 時為分支結點,否則為葉子結點。

若n為奇數,則每個分支結點有左孩子和右孩子,若n為偶數,則編號最大的分支結點只有左孩子結點,其余分支結點都有左右孩子

當 n=2 時滿足

當 n=n-1 時 假設滿足

其實原理很簡單 \[2^{i}=2^{0}+ \cdots + 2^{i-1}\] 所以n/2 也就是倒數第2層 這是全都滿的時候

編號為i的左孩子結點為 2i 右孩子結點為2i+1 雙親結點為: \[ \lfloor 2i\rfloor\]

性質5:

具有n個(n>0)結點的完全二叉樹的高度為\[\lceil log_2{n+1} \rceil \]

7.2.3 二叉樹與樹、森林之間的轉換

1.單棵樹轉換為二叉樹轉換規則

(1) 將樹中所有相鄰兄弟之間加一條連線

(2)將樹中的每個結點只保留它與長子之間的連線,刪除與其他孩子之間的聯系

(3)以樹的根結點為軸心,將整棵樹順時針旋轉45度,使之結構層次分明。

2.森林轉換為二叉樹

(1)將單棵樹按照1規則轉換為二叉樹

(2)第一棵二叉樹不動,從第二棵二叉樹開始,依次把後一棵二叉樹的根結點作為前一棵二叉樹的右孩子結點。

這個轉換的思想:

其實就是將多出來的兄弟結點轉換為右孩子。

1.二叉樹轉換為單棵樹的轉換規則

(1) 若某結點是其雙親的左孩子,則把該結點的右孩子、右孩子的右孩子等都與該結點的雙親結點用連線連起來

(2)刪除原二叉樹中所有雙親結點與右孩子結點之間的連線

(3)逆時針旋轉45度,使之結構層次分明

7.2.4 二叉樹的存儲結構

1.順序存儲結構和鏈式存儲結構

7.2.5 二叉樹的基本運算

1.創建二叉樹 CreateBTree(b,str)

2.銷毀二叉樹 DestroyBTree(&b);

3.查找結點 FindNode(b,x);

4.找孩子結點 LchildNode(p) RchildNode(p);

6.求高度 BTHeight(b);

7.輸出二叉樹DispBTree(b);

7.2.6 二叉樹的遍歷

1.定義

? 二叉樹遍歷是指按照一定的次序訪問二叉樹中的所有結點,並且每個結點僅被訪問一次的過程。

2.種類

?先序遍歷:

1. 先訪問根結點
2. 先序遍歷左子樹
3. 先序遍歷右子樹

?中序遍歷

1.中序遍歷左子樹

2.訪問根結點

3.中序遍歷右子樹

?後序遍歷

1.訪問左子樹

2.訪問右子樹

3.訪問根結點

?層次遍歷

1.從左到右,一層一層地去遍歷

7.2.7 二叉樹的構造

定理7.1:

任何n(n>=0)個不同結點的二叉樹,都可由它的中序序列和先序序列唯一地確定。

證明過程:

先序序列確定了根結點,中序序列確定了左右子樹,

定理7.1:

任何n(n>=0)個不同結點的二叉樹,都可由它的中序序列和後序序列唯一地確定。

證明過程:

後序序列確定了根結點,中序序列確定了左右子樹,

7.2.8 線索二叉樹

1.何為線索(thread):

規定當某結點的左指針為空時,令該指針指向這個線性序列中該結點的前驅結點,當某結點的右指針為空時,令該指針指向這個線性序列中該結點的後繼結點,這樣指向該序列的"前驅結點"、"後繼結點"的指針稱之為線索。

2.創建線索的過程稱為線索化

3.線索化的二叉樹稱之為線索二叉樹(threaded binary-tree)

註意:

為使創建線索二叉樹的算法設計方便,在線索二叉樹在增加一個頭結點。頭結點的data域為空,lchild指向無線索時的根結點,ltag=0,rchild指向按某種方式遍歷二叉樹時最後一個結點,rtag=1

7.2.9 哈夫曼樹

結點的權:結點的值

帶權路徑長度: 從根結點到該結點之間的路徑長度與該結點上的權的乘積(WPL weighted Path Length)

樹的帶權路徑:

? WPL = \[\sum_{i=1}^{n_{0}} w_{i}l_{i}\]

哈夫曼樹(最優二叉樹):

\[n_{0}\]個帶權葉子結點的構成的所有二叉樹中,帶權路徑長度WPL最小的二叉樹

哈夫曼編碼:

編碼: 在數據通信中,將要發送的文字轉換為二進制的0和1組成的二進制字符串。

實質: 使用頻率越高的字符采用最短的編碼

需要編碼的字符集合為\[d_{1},d_{2} \dots ,d_{n}\],出現的頻率為\[{w_{1},w_{2} \dots ,w_{n}}\],字符集合作為葉子結點,頻率集合作為各根結點到每個葉子結點的權值構造一棵哈夫曼樹,規定哈夫曼樹的左分支為0,右分支為1,則從根結點到每個葉子結點所經過的分支對應的0和1組成的序列便是該結點對應字符的編碼,這樣的編碼稱之為哈夫曼編碼。

7.2.10 並查集

定義:

n個不同的元素被分為若幹組,每組是一個集合,這種集合叫分離集合,稱之為並查集。

作用:

高效求解等價類問題

0x8 學習總結

? 不知道最近自己到底在幹嘛,感覺腦子真的不太好使,心裏各種問題就像惡魔一樣糾纏不清,每天都要花費將近\[\frac{5}{6}\]的精力去調節,留給學習的時間真的寥寥無幾,效率對比以前真的特別低,就當作是一種平衡過去那種功利的心態的,每做一點實事都意味著自己邁出了一步,還是希望自己不要那麽懶惰了,加把勁去學習。

?

數據結構學習之第7章 樹和二叉樹