MOOC浙大-資料結構筆記
“線性表(Linear List)”:由同類型資料元素構成有序序列的線性結構
表中元素個數稱為線性表的長度
線性表沒有元素時,稱為空表
表起始位置稱表頭,表結束位置稱表尾
用處舉例:多項式
廣義表(Generalized List)
廣義表是線性表的推廣
對於線性表而言, n個元素都是基本的單元素;
廣義表中,這些元素不僅可以是單元素也可以是另一個廣義表。
多重連結串列: 連結串列中的節點可能同時隸屬於多個鏈
多重連結串列中結點的指標域會有多個,如前面例子包含了Next和SubList兩個指標域;
但包含兩個指標域的連結串列並不一定是多重連結串列,比如在雙向連結串列不是多重連結串列。
多重連結串列有廣泛的用途:基本上如樹、圖這樣相對複雜的資料結構都可以採用多重連結串列方式實現儲存。
多重連結串列的使用舉例:矩陣
矩陣可以用二維陣列表示,但二維陣列表示有兩個缺陷:
一是陣列的大小需要事先確定,
對於“稀疏矩陣 ”,將造成大量的儲存空間浪費。
所以採用一種典型的多重連結串列——十字連結串列來儲存稀疏矩陣
十字連結串列
只儲存矩陣非0元素項
結點的資料域: 行座標Row、列座標Col、數值Value
每個結點通過兩個指標域, 把同行、同列串起來;
行指標(或稱為向右指標)Right
列指標(或稱為向下指標) Down
用一個標識域Tag來區分頭結點和非0元素結點:
頭節點的標識值為“Head”,矩陣非0元素結點的標識值為“Term”。
堆疊(Stack) : 具有一定操作約束的線性表
只在一端(棧頂, Top)做 插入、刪除
插入資料: 入棧(Push)
刪除資料: 出棧(Pop)
後入先出: Last In First Out(LIFO
佇列(Queue): 具有一定操作約束的線性表
插入和刪除操作:只能在一端插入,而在另一端刪除。
資料插入: 入佇列(AddQ)
資料刪除: 出佇列(DeleteQ)
先來先服務
先進先出: FIFO
查詢(Searching): 根據某個給定關鍵字K ,從集合R中找出關鍵字與K相同的記錄
靜態查詢:集合中記錄是固定的
沒有插入和刪除操作,只有查詢
動態查詢:集合中記錄是動態變化的
除查詢,還可能發生插入和刪除
靜態查詢
方法1:順序查詢
順序查詢演算法的時間複雜度為O(n)。
方法2:二分查詢(Binary Search)
二分查詢演算法具有對數的時間複雜度O(logN)
樹(Tree) : n(n≥0)個結點構成的有限集合。
當n=0時,稱為空樹;
對於任一棵非空樹(n> 0),它具備以下性質:
樹中有一個稱為“根(Root) ”的特殊結點, 用 r 表示;
其餘結點可分為m(m>0)個互不相交的有限集T1, T2, ... , Tm,其中每個集合本身又是一棵樹,稱為原來樹的“子樹(SubTree)”
樹的特點:
子樹是不相交的;
除了根結點外, 每個結點有且僅有一個父結點;
一棵N個結點的樹有N-1條邊。
樹的一些基本術語
1. 結點的度(Degree):結點的子樹個數
2. 樹的度:樹的所有結點中最大的度數
3. 葉結點(Leaf): 度為0的結點
4. 父結點(Parent):有子樹的結點是其子樹的根結點的父結點
5. 子結點(Child):若A結點是B結點的父結點,則稱B結點是A結點的子結點;子結點也稱孩子結點。
6. 兄弟結點(Sibling):具有同一父結點的各結點彼此是兄弟結點。
7. 路徑和路徑長度:從結點n1到nk的路徑為一個結點序列n1 , n2 ,… , nk , ni是 ni+1的父結點。路徑所包含邊的個數為路徑的長度。
9. 祖先結點(Ancestor):沿樹根到某一結點路徑上的所有結點都是這個結點的祖先結點。
10. 子孫結點(Descendant):某一結點的子樹中的所有結點是這個結點的子孫。
11. 結點的層次(Level):規定根結點在1層,其它任一結點的層數是其父結點的層數加1。
12. 樹的深度(Depth) :樹中所有結點中的最大層次是這棵樹的深度。
二叉樹T:一個有窮的結點集合。
- 這個集合可以為空
- 若不為空,則它是由根結點和稱為其左子樹TL和右子樹TR的兩個不相交的二叉樹組成。
特殊二叉樹
斜二叉樹(Skewed Binary Tree)
完美二叉樹(Perfect Binary Tree)或滿二叉樹(Full Binary Tree)
完全二叉樹(Complete Binary Tree):有n個結點的二叉樹,對樹中結點按從上至下、從左到右順序進行編號,編號為i(1 ≤ i ≤ n)結點與滿二叉樹中編號為 i 結點在二叉樹中位置相同
二叉樹幾個重要性質
一個二叉樹第 i 層的最大結點數為: 2 i-1, i >= 1。
深度為k的二叉樹有最大結點總數為: 2 k-1, k >= 1。
對任何非空二叉樹 T,若n0表示葉結點的個數、 n2是度為2(即有2個子樹)的非葉結點個數,那麼兩者滿足關係n0 = n2 +1。
證明:
邊的總數=節點數-1=各個節點擁有的邊的總和
n0+n1+n2-1=0*n0+1*n1+2*2n
=>n0=n2+1
二叉搜尋樹(BST, Binary Search Tree),也稱二叉排序樹或二叉查詢樹
二叉搜尋樹:一棵二叉樹,可以為空;如果不為空,滿足以下性質:
1. 非空左子樹的所有鍵值小於其根結點的鍵值。
2. 非空右子樹的所有鍵值大於其根結點的鍵值。
3. 左、右子樹都是二叉搜尋樹
查詢最大和最小元素
最大元素一定是在樹的最右分枝的端結點上
最小元素一定是在樹的最左分枝的端結點上
平衡二叉樹(Balanced Binary Tree)(AVL樹):
空樹,或者任一結點左、右子樹高度差的絕對值不超過1,即|BF(T) |≤ 1
“平衡因子(Balance Factor,簡稱BF) : BF(T) = hL-hR,其中hL和hR分別為T的左、右子樹的高度。
平衡二叉樹的插入與刪除操作太麻煩了,這裡就不多考慮,直接略過吧
堆->優先佇列(Priority Queue):特殊的“佇列” ,取出元素的順序是依照元素的優先權(關鍵字) 大小,而不是元素進入佇列的先後順序。
堆的兩個特性
結構性:用陣列表示的完全二叉樹;
有序性: 任一結點的關鍵字是其子樹所有結點的最大值(或最小值)
“最大堆(MaxHeap)” ,也稱“大頂堆”:最大值
“最小堆(MinHeap)” ,也稱“小頂堆” :最小值
哈夫曼樹的定義
帶權路徑長度(WPL): 設二叉樹有n個葉子結點,每個葉子結點帶有權值 ,從根結點到每個葉子結點的長度為,則每個葉子結點的帶權路徑長度之和就是:
哈夫曼樹或最優二叉樹: WPL最小的二叉樹
哈夫曼樹的構造
每次把權值最小的兩棵二叉樹合併
哈夫曼樹的特點:
沒有度為1的結點;
哈夫曼樹的任意非葉節點的左右子樹交換後仍是哈夫曼樹;
n個葉子結點的哈夫曼樹共有2n-1個結點;
對同一組權值{w1 ,w2 , …… , wn}, 是否存在不同構的兩棵哈夫曼樹呢?
對一組權值{ 1, 2 , 3, 3 }存在 不同構的兩棵哈夫曼樹
哈夫曼編碼
給定一段字串,如何對字元進行編碼,可以使得該字串的編碼儲存空間最少?
如何避免二義性?
字首碼prefix code:任何字元的編碼都不是另一字元編碼的字首
可以無二義地解碼
二叉樹用於編碼
用二叉樹進行編碼:
(1)左右分支: 0、 1(左0右1或者左1右0,選一個)
(2)字元只在葉結點上
怎麼構造一顆編碼代價最小的二叉樹?
使用哈夫曼樹編碼,其原理出現頻率越大的字元,在形成哈夫曼樹的時候就越往後合併,其深度(就是結點的層次)就越小,對應的其編碼位數就越少