1. 程式人生 > >資料結構樹和森林

資料結構樹和森林

知識要點:

樹的結構和主要概念,各種二叉樹的結構及其特點;

二叉樹的三種遍歷方法的實現原理和性質,能將二叉樹的遍歷方法應用於求解二叉樹的葉子結點個數、二叉樹計數等問題,遍歷的非遞迴實現方法;

線索化二叉樹的結構和基本操作;(充分利用二叉樹的空鏈域)

森林的定義和儲存結構,森林的遍歷等方法的實現;(遍歷方式與二叉樹一致)

基於霍夫曼樹生成霍夫曼編碼的方法;

最優二叉樹(霍夫曼樹)的構造原理和相關演算法。

AVL樹的定義和特點以及AVL樹調整操作的實現原理;(平衡二叉樹的建立與調整)

1、樹

樹的定義:含有n個結點的有限集合;n=0時二叉樹為空樹;

1)在非空二叉樹 中有且只有一個被稱為根的結點;

2)其餘結點可以分為多個互不相交的集合,每個集合本身又是一棵樹;

特點:除了根結點之外,每個結點都有前驅結點,樹中所有結點可以有0個或多個後繼結點。

對於含有n個結點的樹,其有n-1條邊;

樹的相關定義(瞭解):

祖先結點:沿著某一路徑到達結點K,K之前的所有結點都為其祖先結點;

子孫結點:從K點沿著某一路徑向下,K之後的所有結點都為其子孫結點;

雙親結點:在K結點上側,且直接與K相互關聯的結點,稱為K的雙親結點;

孩子結點:在K結點下側,且直接與K相互關聯的結點,稱為K的孩子結點;

兄弟結點:位於同一層次上,且雙親結點相同的結點之間互為兄弟結點;

結點的度:該結點所具有的分支數;(由此結點發出的邊的條數)

樹的度:樹中結點度的最大值;

分支結點:度非0的結點,所具有的分支數就是該結點的度;

葉子結點(終端結點):度為0的結點;

結點的層次:根結點位於第一層,由上往下層次數依次加一;

樹的高度(深度):結點的最大層次數;

有序樹和無序樹:不區分子樹的先後順序為無序樹(子樹可以相互交換位置),反之稱為有序樹;

路徑和路徑長度:兩個結點之間的路徑即結點之間所經過的分支,分支的數目稱為路徑長度;

森林:多顆互不相交的樹的集合;

性質:樹中的結點數等於所有結點的度數加1(含有n個結點的樹邊數為n-1)

           樹中有n-1條邊,所有結點的度數為n-1  ->此樹中含有n個結點

           m叉樹中中第i層最多有m^(i-1)個結點;

第一層1個,第二程m個,第三層m^2個,數學歸納法得出第i層最多有m^(i-1)個

           樹高為h的m叉樹最多有(m^h-1)/(m-1)個結點;

           1+m+m^2+.....+m^(h-1) 等比數列求和

           含有n個結點的m叉樹的最小高度為  logm[n(m-1)+1]上取整;

           讓每一層都達到最大結點數,所形成的樹高度最小;

           (m^h-1)/(m-1)>=n且(m^(h-1)-1)/(m-1)<n;求解兩方程得出

           logm[n(m-1)+1]<=h<logm[n(m-1)+1]+1

二叉樹的定義:(遞迴定義且為有序樹子樹之間不能相互變化)

要麼為空樹,要麼滿足以下定義:

1)有且只有一個被稱為根的結點;

2)除了根結點之外,其餘結點又分為兩個互不相交的集合,每個集合又滿足二叉樹的定義(左右子樹);

性質:葉子節點的個數等於度為2的結點個數+1(即  N0=N2+1)

N0+N1+N2=N;

N1+2N2=N-1;聯立兩式得出N0=N2+1

          含有n個結點的二叉樹必有n+1個空指標域(可以用於二叉樹的線索化);

N2=N0-1;N0+N1+N2=n;得出N1+2N0=n+1;(N0提供兩個空指標域,N1提供一個空指標域)

兩種特殊的二叉樹:(完全二叉樹和滿二叉樹)

滿二叉樹:每一層的結點數都達到最大值(即深度為k的二叉樹結點數目為2^k-1,每i層結點為2^(i-1))

完全二叉樹:對二叉樹從根開始由右到左依次標號,與滿二叉樹對應的標號一致則稱之為完全二叉樹;

                      特點:葉子結點只會出現在層次最大的兩層上;

                      性質:含有n個結點的完全二叉樹的深度為,k=(log2[n])(下取整)+1;

                                 完全二叉樹中要麼無度為1的結點,要麼有且只有一個度為1的結點,而且此結點一定無右孩子;

完全二叉樹由上至下,由左往右對結點進行依次編號(i=1時為根結點)

                       1)當i>1時,其雙親結點的值為(i/2)

                       2)2*i<=N時,其左孩子編號為2i,否則無左孩子

                       3)2*i+1<=N時,其左孩子編號為2*i,右孩子編號為2*i+1,否則無右孩子;

二叉樹的四種遍歷方式(先序、中序、後序、層次)

先序遍歷:根->左->右;中序遍歷:左->根->右;中序遍歷:左->右->根;層次遍歷:由上到下,由左到右;

已知中序和其他的任意一種遍歷方式既可以唯一確定一顆二叉樹;

二叉樹的前三種遍歷方式滿足遞迴定義,通過遞迴可以實現(藉助棧結構),層次遍歷需要藉助佇列實現;

二叉樹的存取方式(順序儲存、鏈式儲存):順序存取需要開闢一連續記憶體空間,會有空間上的浪費;對於鏈式存取

設立左右指標域,標明左右子樹關係;

線索二叉樹(充分利用空指標域來表明遍歷的前驅和後繼)方便直接找到遍歷前驅與後繼,加快查詢速度

ltag lchild data rchild rtag

根據遍歷的順序確定當前結點的前驅和後繼;(左前驅,右後繼

ltag=0時,表示該結點有左孩子,左指標域指向左孩子結點;

ltag=1時,表示該結點無左孩子,左指標域指向此結點的前驅結點;

rtag=0時,表示該結點有右孩子,右指標域指向右孩子結點;

rtag=1時,表示該結點無右孩子,左指標域指向此結點的後繼結點;

總結:0表示該結點有對應的孩子,1表示該結點指標域為NULL,指向其前驅和後繼;

樹的表示方法:雙親表示法、孩子表示法、孩子兄弟法(左孩子右兄弟)根結點的右指標域為NULL

☆☆☆樹與森林的轉化:
任何一顆和樹對應的二叉樹其根結點的右子樹必定為空NULL。(左孩子,右兄弟)
(森林和二叉樹可以相互轉化)
森林轉化成二叉樹:
F={T1,T2,....}為一森林集合
如果F為NULL,則次此二叉樹為空樹;
如果F不為空,二叉樹的根即為集合中T1的根,二叉樹的左子樹是T1根結點的子樹森林中轉化而成的二叉樹,
二叉樹的右子樹為原集合中剩餘部分所轉化成的二叉樹。
1、將所有樹先轉化成二叉樹;
2、後一個二叉樹作為前一個二叉樹的右孩子,第一個二叉樹為根。
樹轉化成二叉樹:
1、連線具有相同雙親的兄弟結點
2、除了第一個孩子結點之外,刪除剩餘兄弟結點與雙親的連線。
3、剩餘部分即為生成的二叉樹。

二叉樹轉化成樹:
1、加線:若某結點的左孩子結點存在,則將這個左孩子的右孩子結點、右孩子的右孩子結點、右孩子的右孩子的右孩子結點…,
都作為結點的孩子。將結點與這些右孩子結點用線連線起來。
2、去線:刪除原二叉樹中所有結點與其右孩子結點的連線。
3、層次調整。

二叉樹轉化成森林:
B={root,LB,RB}
如果二叉樹為空:則森林為空
如果二叉樹不為空,則森林中第一顆樹的根為二叉樹的根root,T1中根結點的子樹森林F1是由二叉樹左子樹LB轉化
而成的森林;F中除了T1之外的其餘樹組成的森林F'={T2,T3,...}是由二叉樹B的右子樹轉化而來的。

1、斷開從根結點沿著右下角路徑上的所有連線。
2、將生成的二叉樹變成森林即可。

樹、二叉樹、森林轉化的總結:

1、樹轉化為二叉樹:連線所有的兄弟結點,去除除了第一個結點之外的其他與父節點的連線,

以根為軸心順時針旋轉45度;

(二叉樹轉化為樹與之相反)

2、森林轉化為二叉樹:將森林中的每一顆樹轉化成二叉樹。

連線新生成二叉樹的每一個根結點(第一顆樹的根結點為生成二叉樹的樹根,有指標域指向第二顆子樹,依次類推);

以根為旋轉軸順時針旋轉45度;

3、二叉樹轉化為森林:斷開從根結點開始一直向右下方的所有連線,生成多顆二叉子樹,

將每顆二叉子樹轉化成樹即可構成森林;

樹、森林、二叉樹的遍歷之間的關係:

樹和森林的遍歷與二叉樹遍歷的對應關係
森林 二叉樹
先根遍歷 先序遍歷 先序遍歷
後根遍歷 中序遍歷 中序遍歷

哈夫曼樹(哈夫曼編碼):左零右一,哈夫曼編碼為最優字首編碼,葉子結點儲存資料

字首編碼:任何一個編碼都不是另一個編碼的字首則此編碼稱為字首編碼;

哈夫曼樹為帶權路徑長度最小的樹,其樹形並不唯一,但所求權值一定相同

☆☆☆哈夫曼樹的構造:(左0右1

1)有N個結點各自為根形成一個集合(森林)

2)從集合中選取最小的兩個值作為葉子結點,生成一顆新樹,此樹根結點的權值為葉子結點的權值之和;

如果權值相同,優先選用高度最小的;將原樹結點刪除,將新生成的樹加入集合(森林)中;

3)重複2步驟直到森林中只有一顆樹,該樹就為哈夫曼樹;

二叉排序樹(BST):要麼為一顆空樹,要麼滿足一下定義(遞迴定義)

                                    1)左子樹非空,則左子樹中任意結點的值小於根節點的值;

                                    2)右子樹非空,則右子樹中任意結點的值大於根結點的值;

                                    3)左右子樹又滿足一顆二叉排序樹的定義;

特點:中序遍歷得到的是一個有序序列。對於二叉排序樹的查詢最優時間複雜度為O(log2n),最壞為單支樹的情況O(n);

所以二叉排序樹的查詢效率與樹形(高)有關;若本身插入的構造資料有序,則此二叉排序樹為單支樹;

二叉排序樹的刪除:1)如果是葉子結點則直接刪除;(不影響二叉排序樹的性質)

                                 2)如果為非葉子結點且只有一顆左或右子樹,則直接讓子樹的根結點代替原刪除結點即可;

                                 3)如果為非葉子結點且有左右子樹,則讓子樹中的子女位置填充刪除結點的位置;

                                       比如右子樹中最左側的結點或者左子樹中最右側的結點;

平衡二叉樹:

定義:要麼為空樹,要麼滿足一下定義;

每個結點的左右子樹的深度之差(平衡因子)的絕對值不超過1;(平衡因子只能是-1,0,1)

☆☆☆重點:對於平衡二叉樹的調整:(左逆右順,負負得正

LL型:在A結點左子樹根結點的左子樹插入結點,導致A結點平衡因子由1變2

           進行一次順時針旋轉;將原根結點的左孩子作為新生成樹的根結點,將左孩子的右子樹作為原樹根結點的左孩子。

RR型:在A結點右子樹根結點的右子樹插入結點,導致A結點平衡因子由-1變-2

           進行一次逆時針旋轉;將原根結點的右孩子作為新生成樹的根結點,將右孩子的左子樹作為原樹根結點的右孩子。

LR型:在A結點左子樹根結點的右子樹插入結點,導致A結點平衡因子由1變2

           先逆時針旋轉一次,後順時針旋轉一次;

           將新插入的部分作為此插入結點父節點的右孩子,逆時針旋轉一次,將此結點作為此子樹的根結點,將其原父節點作為此            結點的左孩子,再將此結點的右孩子作為原樹根結點的左孩子,順時針旋轉一次,將此結點作為整個樹的根結點,將原根            結點作為新生成樹的右孩子。

RL型:在A結點右子樹根結點的左子樹插入結點,導致A結點平衡因子由-1變-2

           先順時針旋轉一次,後逆時針旋轉一次;

          將新插入的部分作為此插入結點父節點的左孩子,順時針旋轉一次,將此結點作為此子樹的根結點,將其原父節點作為此              結點的右孩子,再將此結點的左孩子作為原樹根結點的右孩子,逆時針旋轉一次,將此結點作為整顆樹的根結點,將原根            結點作為新生成樹的左孩子。

高度為h的平衡二叉樹結點的最小值問題:N1=1、N2=2、N3=4、N4=7

                                                                   遞推公式Nh=Nh-1+Nh-2+1;(前兩項的值的和加1)