資料結構樹和森林
知識要點:
樹的結構和主要概念,各種二叉樹的結構及其特點;
二叉樹的三種遍歷方法的實現原理和性質,能將二叉樹的遍歷方法應用於求解二叉樹的葉子結點個數、二叉樹計數等問題,遍歷的非遞迴實現方法;
線索化二叉樹的結構和基本操作;(充分利用二叉樹的空鏈域)
森林的定義和儲存結構,森林的遍歷等方法的實現;(遍歷方式與二叉樹一致)
基於霍夫曼樹生成霍夫曼編碼的方法;
最優二叉樹(霍夫曼樹)的構造原理和相關演算法。
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)