1. 程式人生 > >MOOC浙大-資料結構筆記

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個葉子結點,每個葉子結點帶有權值 W_{k},從根結點到每個葉子結點的長度為L_{k},則每個葉子結點的帶權路徑長度之和就是:

                                                    WPL= \sum_{n}^{k=1}W_{k}L_{k}

哈夫曼樹或最優二叉樹: WPL最小的二叉樹

哈夫曼樹的構造
 每次把權值最小的兩棵二叉樹合併

 哈夫曼樹的特點:

 沒有度為1的結點;
 哈夫曼樹的任意非葉節點的左右子樹交換後仍是哈夫曼樹;
 n個葉子結點的哈夫曼樹共有2n-1個結點;
 對同一組權值{w1 ,w2 , …… , wn}, 是否存在不同構的兩棵哈夫曼樹呢?
對一組權值{ 1, 2 , 3, 3 }存在 不同構的兩棵哈夫曼樹


哈夫曼編碼
 給定一段字串,如何對字元進行編碼,可以使得該字串的編碼儲存空間最少?

如何避免二義性?
 字首碼prefix code:任何字元的編碼都不是另一字元編碼的字首
    可以無二義地解碼

二叉樹用於編碼
用二叉樹進行編碼:
(1)左右分支: 0、 1(左0右1或者左1右0,選一個)
(2)字元只在葉結點上

怎麼構造一顆編碼代價最小的二叉樹?
使用哈夫曼樹編碼,其原理出現頻率越大的字元,在形成哈夫曼樹的時候就越往後合併,其深度(就是結點的層次)就越小,對應的其編碼位數就越少