第一章 概論
- 概論⭐⭐
- 資料結構:計算機組織資料和儲存資料的方式。
- 資料結構:指一組相互之間存在一種或多種特定關係的資料的組織方式和它們在計算機內的儲存方式,以及定義在該組資料上的一組操作。
- 引言⭐⭐
- 演算法+資料結構=程式
- 資料、資料元素和資料項⭐⭐⭐
- 資料:所有被計算機儲存、處理的物件。
- 資料元素:資料的基本單位,是運算的基本單位。常常又簡稱為元素。
- 資料項:是資料的不可分割的最小標識單位。在資料庫中資料項又稱為欄位。
- 資料、資料元素、資料項之間的關係:從宏觀上來看,資料、資料元素和資料項實際上反映了資料組織的三個層次,資料可由若干個資料元素組成,而資料元素又可由若干資料項組成。
- 資料結構是相互之間存在一種或多種特定關係的資料元素的組合。它包括資料的邏輯結構、資料的儲存結構和資料的基本運算。
- 資料的邏輯結構⭐⭐⭐
- 集合:任意兩個結點之間都沒有鄰接關係,組織形式鬆散。(一盤散沙)
- 線性結構:結點按邏輯關係依次排列形成一條“鏈”,結點之間一個一個依次相鄰接。
- 樹形結構:具有分支、層次特性,其形態像自然界中的樹,上層的結點可以和下層多個結點相鄰接,但下層結點只能和上層一個結點相鄰接。
- 圖結構:最複雜,其中任何兩個結點都可以相鄰接。
- 資料的儲存結構⭐⭐⭐
- 順序儲存方式:指所有儲存結點存放在一個連續的儲存區裡。利用結點在儲存器中的相對位置來表示資料元素之間的邏輯關係。
- 鏈式儲存方式:指每個儲存結點除了含有一個資料元素外,還包含指標,每個指標指向一個與本結點有邏輯關係的結點,用指標表示資料元素之間的邏輯關係。
- 除了上述兩種儲存方式之外 ,還有索引儲存方式和雜湊儲存方式。但主要的儲存方式是:順序儲存方式和鏈式儲存方式。
- 運算⭐
- 運算包括:建立、查詢、讀取、插入和刪除等。
- 線性表、棧和佇列中的元素具有相同的邏輯結構(即線性結構),但有不同的運算集,它們是不同的資料結構。
- 評價演算法好壞的因素⭐⭐⭐
- 正確性:能正確地實現預定的功能,滿足具體問題的需要。
- 易讀性:易於閱讀、理解和交流,便於除錯、修改和擴充。
- 健壯性:即使輸入非法資料,演算法也能適當地做出反應或進行處理,不會產生預料不到的執行結果。
- 時空性:指該演算法的時間效能(或時間效率)和空間效能(或空間效率),前者是演算法包含的計算量,後者是演算法需要的儲存量。
- 時間複雜度⭐⭐⭐
- 常見的時間複雜度的比較:
- O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(nc)<O(2n)
- O(1) 無迴圈、無遞迴
- O(log2n) 無迴圈、有遞迴
- O(n) 一層迴圈
- O(nlog2n) 一層迴圈+遞迴
- O(n^2) 雙層迴圈
- O(n^c) c層迴圈
- O(2^n) 實際不可計算的。
- O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(nc)<O(2n)
- 常見的時間複雜度的比較:
- 空間複雜度⭐
- 是對一個演算法在執行過程中臨時佔用儲存空間大小的量度。儲存空間量應包括:
- 程式程式碼所佔用的空間;
- 輸入資料所佔用的空間
- 輔助變數所佔用的空間,估算時,一般只需要分析輔助變數所佔用的空間。
- 是對一個演算法在執行過程中臨時佔用儲存空間大小的量度。儲存空間量應包括:
第二章 線性表
- 線性表的基本概念⭐⭐
- 概念:線性表是一種線性結構,由n(n≧0)個資料元素組成的有窮序列,資料元素又稱結點。結點個數 n 稱為表長。a1稱為起始節點,an稱為終端結點。
- 基本特徵:線性表中結點具有一對一的關係,如果結點數不為零,則:
- 除起始結點沒有直接前驅外,其他每個結點有且僅有一個直接前驅;
- 除終端結點沒有直接後繼外,其他每個結點有且僅有一個直接後繼。
- 順序表實現演算法的分析⭐⭐⭐
- 單連結串列的型別定義⭐⭐⭐
- 結點結構
- 資料域(data),用於儲存線性表的一個資料元素。
- 指標域或鏈域(next),用於存放一個指標,該指標指向本結點所含資料元素的直接後繼結點。
- 單連結串列:所有結點透過指標連結形成連結串列。
- 頭指標:head稱為頭指標變數,該變數的值是指向單連結串列的第一個結點的指標。
- 首結點:連結串列中第一個資料元素稱為連結串列的首結點。
- 尾結點:連結串列中最後一個資料元素結點稱為尾結點或終端結點。尾結點指標域的值NULL稱為空指標,它不指向任何結點,表示連結串列結束。
- 帶頭結點的單連結串列:在單連結串列的第一個結點之前增設一個型別相同的結點,稱為頭結點。
- 結點結構
- 線性表的基本運算在單連結串列上的實現⭐⭐⭐
- 插入:插入p指向新結點的操作
- ① p->next=q->next; ② q->next=p;
- 刪除:刪除*p結點的操作
- q->next=p->next;
- 插入:插入p指向新結點的操作
- 迴圈連結串列⭐⭐
- 在單連結串列中,如果讓最後一個結點的指標域指向第一個結點可以構成迴圈連結串列。
- 判斷p所指結點的尾結點的條件:p->next==head;
- 判斷指標p所指結點為首結點的條件:p==rear->next->next;
- 判斷連結串列是否為空的條件:head->next==head;
- 在單連結串列中,如果讓最後一個結點的指標域指向第一個結點可以構成迴圈連結串列。
- 雙向迴圈連結串列⭐⭐⭐
- 每個結點有兩個指標,next指標指向直接後繼結點;prior指標指向直接前驅結點。
- 帶頭結點的雙向迴圈連結串列L為空的條件:(L->nextL) && (L->priorL)
- 刪除
- 設p指向待刪結點,刪除*p的操作:
- p->prior->next=p->next;
- p->next->prior=p->prior;
- free(p)
- 以上前兩條語句順序可顛倒。
- 設p指向待刪結點,刪除*p的操作:
- 插入
- 在p所指結點的後面插入一個新結點 *t 的操作:
- t->prior=p;
- t->next=p->next;
- p->next->prior=t;
- p->next=t;
- 在p所指結點的後面插入一個新結點 *t 的操作:
- 順序實現與連結實現的比較⭐
第三章 棧、佇列和陣列
-
棧、佇列和陣列⭐⭐
- 棧和佇列可看作是特殊的線性表。它們是運算受限的線性表。棧和佇列也同樣有兩種儲存結構(順序儲存結構和鏈式儲存結構)。
-
棧的基本概念⭐⭐⭐
- 棧:這種線性表上的插入和刪除運算限定在表的某一端進行。允許進行插入和刪除的一端稱為棧頂,另一端稱為棧底。不含任何資料元素的棧稱為空棧。
- 棧的修改原則:後進先出,棧又稱為後進先出線性表,簡稱後進先出表。
- 棧的基本運算:
- 初始化 InitStack(S):構建一個空棧S;
- 判棧空 EmptyStack(S):若棧S為空棧,則結果為1,否則結果為0;
- 進棧 Push(S, x):將元素 x 插入到棧S中,使x成為棧S的棧頂元素;
- 出棧 Pop(S):刪除棧頂元素;
- 取棧頂 GetTop(S):返回棧頂元素。
-
棧的順序實現⭐⭐
- 下溢:當空棧,棧頂下標值 top=0,如果此時做出棧運算,則產生“下溢”。
- 上溢:當棧中的資料元素已經填滿了,如果再進行進棧操作,會發生“上溢”。
- 初始化:
- 判棧空:
- 進棧:
- 出棧:
- 取棧頂元素:
-
佇列的基本概念⭐⭐⭐
- 是一種先進先出的線性表,新加入的資料元素插在佇列尾端,出佇列的資料元素在佇列首部被刪除。
-
佇列的順序實現⭐⭐⭐
- 迴圈佇列:為了避免元素的移動,將儲存佇列元素的一維陣列首尾相接,形成一個環狀。
- 入隊列操作語句:SQ.rear=(SQ.rear+1) % maxsize; SQ.data[SQ.rear]=x;
- 出隊列賦值語句:SQ.fronts(SQ.front+1) % maxsize;
- 迴圈佇列滿:((CQ.rear +1) % maxsize == CQ.front) 成立
- 佇列空條件:(CQ.rear==CQ.front) 成立
- 佇列中元素個數公式:陣列Q[n] 表示一個迴圈佇列,設 f 為佇列中第一個元素的位置,r 為佇列中實際隊尾的位置加1,則佇列中元素的個數公式:(r-f+n) %n
-
佇列的連結實現⭐
- 由於連結實現需要動態申請空間,故鏈佇列在一定範圍內不會出現佇列滿的情況。
- 佇列判空:當 (LQ.front==LQ.rear) 成立時,佇列中無資料元素,此時佇列為空。
- 在實現佇列的連結串列結構中,僅設定尾指標的單迴圈連結串列的時間複雜度最優。
-
陣列的儲存結構⭐⭐⭐
- 資料元素的儲存位置是下標的線性函式:對於二維陣列
a[m][n]
,如果每個元素佔 k 個儲存單元,以行為主序為例,討論陣列元素a[i][j]
位置與下標的關係:- 由於下標從0開始,元素
a[i][j]
之前已經有 i 行元素,每行有n個元素,在第 i 行,有 j+1 個元素,總共有n*i+j+1
個元素,第一個元素與a[i][j]
相差n*i+j+1-1
個位置,故a[i][j]
的位置為:loc[i, j]=loc[0, 0]+(n*i+j)*k
。
- 由於下標從0開始,元素
- 資料元素的儲存位置是下標的線性函式:對於二維陣列
-
矩陣的壓縮儲存⭐⭐⭐
- 為了節省儲存空間,對這類矩陣採用多個值相同的元素只分配一個儲存空間,零元素不儲存的策略,這一方法稱為矩陣的壓縮儲存。
- 特殊矩陣:如果值相同的元素或者零元素在矩陣中的分佈有一定規律,稱此類矩陣為特殊矩陣。
- 對稱矩陣:若一個 n 階方陣A中的元素滿足下述條件:則稱A為對稱矩陣。
- 對稱矩陣有近一半的元素可以透過其對稱元素獲得,為每一對對稱元素只分配一個儲存單元,則可將n2個元素壓縮儲存到含有n(n+1)/2個元素的一維陣列中。
- 三角矩陣:以主對角線為界的上(下)半部分是一個固定的值c或零,這樣的矩陣叫做下(上)三角矩陣。(哪邊不為c或0就是該方向的三角矩陣)
- 稀疏矩陣:非零元素很少的矩陣。
- 三元組表示法:用三個項來表示稀疏矩陣中的非零元素aij,即(i, j, aij),其中 i 表示行序號,j 表示列序號,aij 是非零元素的值,通常稱為三元組。
- 對稱矩陣:若一個 n 階方陣A中的元素滿足下述條件:則稱A為對稱矩陣。
第四章 樹和二叉樹
-
樹的概念⭐
- 樹是n(n≥0)個結點的有限集合,一棵樹滿足以下兩個條件:
- 當n=0時,稱為空樹;
- 當n>0時,有且僅有一個稱為根的結點,除根結點外,其餘結點分 m(m≥0)個互不相交的非空集合 T1, T2, ..., Tm,這些集合中的每一個都是一棵樹,稱為根的子樹。
- 樹是n(n≥0)個結點的有限集合,一棵樹滿足以下兩個條件:
-
樹的相關術語⭐⭐⭐
- 結點的度:樹上任一結點所擁有的子樹的數目稱為該結點的度。
- 葉子:度為0的結點稱為葉子或終端結點。
- 樹的度:一棵樹中所有結點的度的最大值稱為該樹的度。
- 一個結點的子樹的根稱為該結點的孩子(或稱子結點)。相應地該結點稱為孩子的雙親(也稱父結點)。父結點相同的結點互稱為兄弟。
- 結點的層次:從根開始算起,根的層次為1,其餘結點的層次為其雙親的層次加1。
- 樹的高度:一棵樹中所有結點層次數的最大值稱為該樹的高度或深度。
- 對於任一個樹都有:結點數=分支樹+1
-
二叉樹的基本概念⭐
- 二叉樹是n(n≥0)個元素的有限集合,該集合或者為空,或者由一個根及兩棵互不相交的左子樹和右子樹組成,其中左子樹和右子樹也均為二叉樹。
- 注意:左右子樹次序不可換,都可為空。
-
二叉樹的性質⭐⭐⭐
- 滿二叉樹:深度為 k(k≥1)且有2k-1個結點的二叉樹稱為滿二叉樹。由性質2知,滿二叉樹上的結點數已達到了二叉樹可以容納的最大值。
- 完全二叉樹:如果對滿二叉樹按從上到下,從左到右的順序編號,並在最下一層刪去部分結點(刪後最後一層仍有結點),如果刪除的這些結點的編號是連續的且刪除的結點中含有最大編號的結點,那麼這棵二叉樹就是完全二叉樹。
-
二叉樹的順序儲存結構⭐
- 二叉樹的順序儲存結構可以用一維陣列來實現。
- 如果需要順序儲存的非完全二叉樹,首先必須用某種方法將其轉化為完全二叉樹,為些可增設若干個虛擬結點。會造成空間的浪費。
-
二叉樹的鏈式儲存結構⭐⭐⭐
- 二叉樹有不同的鏈式儲存結構,其中最常用的是二叉連結串列或三叉連結串列。其結點形式如下:
- 二叉連結串列:具有n個結點的二叉樹中,共有2n個指標域,其中只有 n-1 個用來指向結點的左、右孩子(因為沒有指向根結點的指標域),其餘的 n+1 個指標域為 NULL。
-
二叉樹遍歷的遞迴實現⭐⭐⭐
-
應用舉例⭐
- 由一個二叉樹的後序序列和中序序列,可以唯一確定一棵二叉樹。
- 由一個二叉樹的先序序列和中序序列,也可以唯一確定一棵二叉樹。
- 注意:必須要有中序序列。
-
樹的儲存結構⭐
- 孩子連結串列表示法:樹上的一個結點 X 以及該結點的所有孩子結點組成一個帶頭結點的單連結串列。
- 頭結點含有兩個域:資料域和指標域。其中,資料域用於儲存結點 X 中的資料元素,指標域用於儲存指向 X 第一個孩子結點的指標。
- 表結點也含兩個域:孩子域(child)和指標域(next),孩子域儲存其中一個孩子的序號,指標域指向其下一個孩子的結點。
- 孩子兄弟連結串列表示法:儲存時每個結點除了資料域外,還有指向該結點的第一個孩子和下一個兄弟結點的指標。
- 注意:孩子兄弟連結串列的結構形式與二叉連結串列完全相同,但結點中指標的含義不同。二叉連結串列中結點的左、右指標分別指向左、右孩子;而孩子兄弟連結串列中結點的兩個指標分別指向孩子和兄弟。
- 雙親表示法:由一個一維陣列構成。資料的每個分量包含兩個域:資料域和雙親域。
- 資料域用於儲存樹上一個結點中的資料元素,雙親域用於儲存本結點的雙親結點在陣列中的序號值(下標值)。
- 孩子連結串列表示法:樹上的一個結點 X 以及該結點的所有孩子結點組成一個帶頭結點的單連結串列。
-
樹、森林與二叉樹的關係⭐
- 樹轉換成二叉樹
- 將所有兄弟結點連線起來;
- 保留第一個兄弟結點與父結點的連線,斷開其他兄弟結點與父結點的連線
- 然後以根結點為軸心按順時針的方向旋轉45⁰ 角。
- 森林轉換成二叉樹
- 將每棵樹轉換成相應的二叉樹;
- 將上邊得到的各棵二叉樹的根結點看作是兄弟連線起來。
- 二叉樹轉換成森林
- 在待轉換的二叉樹中,斷開根結點與右孩子的連線,得到兩棵二叉樹,其中一棵是以二叉樹B的根結點為根的二叉樹,另一棵是以根結點的右孩子E 為根結點的二叉樹。
- 樹轉換成二叉樹
-
森林的遍歷⭐⭐
-
分類與判定樹⭐
- 分類:一種常用運算,其作用是將輸入資料按預定的標準劃分成不同的種類。
- 判定樹:用於描述分類過程的二叉樹。
-
哈夫曼(Huffman)樹與哈夫曼演算法⭐⭐⭐
- 哈夫曼樹:給定一組值 p1 ..., pk,如何構造一棵有 k 個葉子且分別以這些值為樹的判定樹,使得其平均比較次數(WPL)最小。滿足上述條件的判定樹稱為哈夫曼樹。其中Pi 是第 i 個結點的權值,li 是第 i 個結點的比較次數。
- 哈夫曼演算法:哈夫曼給出的一個求哈夫曼樹的簡單而有效的方法,稱為哈夫曼演算法。具體方法如下:
- ①由給定的值{p1, ..., pk} 構造森林 F={T1, ..., Tk},其中每個Ti為一棵只有根結點且其權為pi的二叉樹。
- ②從F中選取根結點的權最小的兩棵二叉樹Ti、Tj,構造一棵分別以Ti 和Tj 為左、右子樹的新的二叉樹Th,置Th根結點的權為Ti 和 Tj 根結點的樹值之和。
- ③從F中刪去Ti 、Tj,並將Th 加入F。若F中仍多於一棵二叉樹,則返回②,直到F中只含一棵二叉樹為止,這棵二叉樹就是哈夫曼樹。
- 結論:最終求得的哈夫曼樹中共有結點總數:2n-1 個。其中,n個葉結點是初始森林中的n個結點,合併 n-1 次共產生 n-1 個新結點,且哈夫曼樹中沒有度數為1的分支結點。
第五章 圖
- 圖的定義和術語⭐⭐
- 無向完全圖:任何兩點之間都有邊的無向圖稱為無向完全圖。一個具有n個頂點的無向完全圖的邊數為 n(n-1) /2。
- 有向完全圖:任何兩點之間都有弧的有向圖稱為有向完全圖。一個具有n個頂點的有向完全圖的弧數為 n(n-1)。(有向圖的邊稱為弧)
- 度:
- 無向圖的度:無向圖中頂點v的度是與該頂點相關聯的邊的數目,記為 D(v)。
- 有向圖的入度:有向圖中以頂點v為終點的弧的數目稱為v的入度,記為 ID(v)。
- 有向圖的出度:有向圖中以頂點v為始點的弧的數目稱為v的出度,記為 OD(v)。
- 有向圖的度:有向圖中頂點v的度為入度和出度之和,即 D(v)=ID(v)+OD(v)。
- 連通:在無向圖中,如果從頂點v到頂點v’ 有路徑,則稱v和v’ 是連通的。
- 連通圖:如果圖中的任意兩個頂點vi和vj都是連通的,則稱G為連通圖。
- 連通分量:是無向圖中的極大連通子圖。
- 強連通圖:對於有向圖來說,如果圖中任意一對頂點vi和vj(其中i≠j)都有頂點vi 到頂點 vj的路徑,也有從vj 到vi 的路徑,即兩個頂點間雙向連通。
- 強連通分量:有向圖的極大強連通子圖。
- 生成樹:一個連通圖的生成樹,是含有該連通圖的全部頂點的一個極小連通子圖。
- 鄰接矩陣⭐⭐⭐
- 用矩陣來描述圖中頂點之間的關聯關係,用二維陣列來實現矩陣。設G=(V, E)是一個圖,其中V={v0, v1, ..., vn-1},那麼G的鄰接矩陣A定義為如下n階方陣:
- 無向圖的鄰接矩陣是一個對稱矩陣。
- 有向圖
- 頂點vi的出度 OD(vi) 是鄰接矩陣中第 i 行元素之和。
- 頂點vi的入度 ID(vi) 是鄰接矩陣中第 i 列元素之和。
- 鄰接表⭐
- 鄰接表是順序儲存與鏈式儲存相結合的儲存方法。
- 圖的遍歷⭐⭐⭐
- 深度優先搜尋
- 類似於樹的先序遍歷。
- 基本思想:假定以圖中某個頂點vi 為出發點,首先訪問出發點 vi,然後任選一個vi 的未訪問過的鄰接點 vj,以vj 為新的出發點繼續進行深度優先搜尋,依此類推,直至圖中所有頂點都被訪問過。深度優先搜尋遍歷類似於樹的先序遍歷。圖的深度優先搜尋可以看成一個遞迴過程。
- 注意兩點:
- 1、搜尋到達某個頂點時(圖中仍有頂點未被訪問),如果這個頂點的所有鄰接點都被訪問過,那麼搜尋就要回到前一個被訪問過的頂點,再從該頂點的下一未被訪問的領接點開始深度優先搜尋;
- 2、深度搜尋的頂點的訪問序列不是唯一的。
- 時間複雜度
- 採用鄰接矩陣作為儲存結構的圖的時間複雜度:O(n2),其中n 為圖的頂點數。
- 採用鄰接表作為儲存結構的圖的時間複雜度:O(n+e),其中n 為圖的頂點數,e為圖的邊數。
- 廣度優先搜尋
- 類似於樹的按層次遍歷的過程。
- 基本思想:從圖中某個頂點vi 出發,在訪問了vi 之後依次訪問vi 的所有鄰接點,然後依次從這些鄰接點出發按廣度優先搜尋方法遍歷圖的其他頂點,重複這一過程,直至所有頂點都被訪問到。類似於樹的按層次遍歷的過程。
- 深度優先搜尋
- 最小生成樹⭐⭐
- 一個圖的最小生成樹是圖所有生成樹中權總和最小的生成樹。
- 最小生成樹的演算法有:Prim演算法 和 克魯斯卡爾(Kruskal)演算法
- 求單源最短路徑——迪傑斯特拉(Dijkstra)演算法
- 拓撲排序⭐⭐
- AOV網:如果以圖中的頂點來表示活動,有向邊表示活動之間的優先關係,這種用頂點表示活動的有向圖稱為 AOV網。AOV網中的弧表示了活動之間存在著的制約關係。
- 拓撲排序:拓撲排序的演算法的時間複雜度為O(n+e),n是圖的頂點個數,e是圖的弧的數目。
第六章 查詢
- 基本概念⭐⭐
- 查詢表(Search Table)是由同一型別的資料元素構成的集合,它是一種以查詢為“核心”,同時包括其他運算的非常靈活的資料結構。其分類有:
- 靜態查詢表:建表、查詢 、讀表中元素
- 動態查詢表:初始化、查詢、讀表中元素、插入、刪除
- 查詢表(Search Table)是由同一型別的資料元素構成的集合,它是一種以查詢為“核心”,同時包括其他運算的非常靈活的資料結構。其分類有:
- 順序表上的查詢⭐⭐
- 靜態查詢表最簡單的實現方法是以順序表作為儲存結構,即鏈式儲存結構。
- 查詢成功時的平均查詢長度,記為ASL:,其中,Pi為查詢第i個元素(即給定值key與順序表中第i個元素的鍵值相等)的機率,且,Ci 表示在找到第 i 個元素時,與給定值已進行比較的鍵值個數。
- 有序表上的查詢⭐⭐⭐
- 有序表:如果順序表中資料元素是按照鍵值大小的順序排列的,則稱為有序表。適用於二分查詢。
- 二分查詢:用給定值key與處在中間位置的資料元素T.elem[mid]的鍵值T.elem[mid].key 進行比較,可根據三種比較結果區分三種情況:
- key=T.elem[mid].key,查詢成功,T.elem[mid]即為待查元素;
- key<T.elem[mid].key,說明若待查元素在表中,則一定排在T.elem[mid] 之前;
- key>T.elem[mid].key,說明若待查元素在表中,則一定排在T.elem[mid] 之後。
- 平均查詢長度:二分查詢的平均查詢長度為
- 二分查詢演算法平均時間複雜度:O(log2n)
- 二叉排序樹⭐⭐
- 定義:一棵二叉排序樹(又稱二叉查詢樹)或者是一棵空二叉樹,或者是具有下列性質的二叉樹:
- 若它的左子樹不空,則左子樹上所有結點的鍵值均小於它的根結點鍵值;
- 若它的右子樹不空,則右子樹上所有結點的鍵值均大於它的根結點鍵值;
- 根的左、右子樹也分別為二叉排序樹。
- 二叉排序樹上平均查詢長度是介於O(n)和O(log2n)之間的。
- 定義:一棵二叉排序樹(又稱二叉查詢樹)或者是一棵空二叉樹,或者是具有下列性質的二叉樹:
- 雜湊表⭐
- 資料元素的鍵值和儲存位置之間建立的對應關係 H 稱為雜湊函式,用鍵值透過雜湊函式獲取儲存位置的這種儲存方式構造的儲存結構稱為雜湊表。
- 設有雜湊函式 H 和鍵值 k1、k2(k≠k2),若 H(k1)=H(k2),則這種現象稱為“衝突”,且稱鍵值 k1 和 k2 互為同義詞。
- 常用雜湊法⭐⭐
- 數字分析法:又稱資料選擇法,其方法是收集所有可能出現的鍵值,排列在一起,對鍵值的每一位進行分析,選擇分佈較均勻的苦幹位組成雜湊地址。所取的位數取決於雜湊表的表長,見表長100,則取2位即可。
- 除留餘數法:是一種簡單有效且最常用的構造方法,其方法是選擇一個不大於雜湊表長n的正整數p,以鍵值除以p所得的餘數作為雜湊地址,即H(key)=key mod p (p≤n),注意:通常選p為小於雜湊表長度n的素數。
- 平方取中法:以鍵值平方的中間幾位作為雜湊地址。通常在選定雜湊函式時不一定能知道鍵值的分佈情況。所得雜湊地址比較均勻。
- 基數轉換法:將鍵值看成另一種進位制的數再轉換成原來進位制的數,然後選其中幾位作為雜湊地址。
- 雜湊表的實現⭐⭐
- 線性探測法:對任何鍵值key,設H(key)=d,設雜湊表的容量為m,則線性探測法生成的後繼雜湊地址序列為 d+1,d+2, ..., m-1, 0, 1, ..., d-1
- 二次探測法:生成的後繼雜湊地址不是連續的,而是跳躍式的,以便為後續資料元素留下空間從而減少堆積。按照二次探測法,鍵值key的雜湊地址序列為d0=H(key); d1=(d0+i) mod m。其中,m為雜湊表的表長,i=12,-12,22,-22,...,\(\pm\) k2(k≤m/2)。
第七章 排序
- 概述⭐⭐
- n個記錄的序列為{R1, R2, ..., Rn},其相應的鍵值序列為{k1, k2, ..., kn},假設ki=kj,若在排序前的序列中Ri在Rj之前,即 i<j,經過排序後,Ri 仍在Rj 之前,則稱所用的排序方法是穩定的;反之,則稱所用的排序方法是不穩定的。
- 穩定性是排序方法本身的特性,與資料無關。
- 4種排序方法⭐⭐⭐