緒論
- 數據:數據是信息的載體,信息是數據的內涵。
- 數據元素:數據的基本單位。
- 數據項:構成數據元素不可分割的最小單位。
- 數據對象:性質相同的數據元素的集合,是數據的子集。
- 數據類型:一個值的集合以及定義在此集合上一組操作的總稱。原子類型、結構類型、抽象數據類型ADT。
- 抽象數據類型ADT:只關係邏輯結構,無需關係具體實現、存儲結構。由數據對象、數據關係、基本操作組成。
- 數據結構:相互之間存在一種或多種特定關係的數據元素的集合。數據結構=數據元素+數據關係。
- 數據結構三要素:邏輯結構、物理結構、數據運算。
- 邏輯結構:數據元素之間的邏輯關係。線性結構、非線性結構。
線性結構:線性表1:1、棧、隊列、串、數組。
非線性結構:集合,除同屬一個集合別無其他關係;樹,1:n;圖,m:n。 - 存儲結構:數據結構在計算機上的表示,順序存儲、鏈式存儲、索引存儲、散列存儲。
- 數據運算:運算的定義依賴於邏輯結構,運算的實現依賴於物理結構。
- 算法:特定問題求解步驟的描述。
- 算法五特性:確定性、可行性、有窮性、輸入、輸出。
- 優質算法特性:正確性、健壯性、可讀性、高效率、低存儲(時空複雜度低)。
- 算法分析:時間複雜度、空間複雜度、穩定性。
- S(n)=O(1):算法原地工作指算法所需要的輔助空間爲常量。
- 程序=數據結構+算法:數據結構是要處理的信息,算法是處理信息的步驟。
線性表
- 順序表:線性表的順序存儲,邏輯順序和物理順序相同。隨機訪問,存儲密度高,插入刪除需要移動大量元素。靜態順序表、動態順序表。
靜態線性表:數組、大小固定、少則內存溢出、多則資源浪費。
動態線性表:動態分配存儲空間。 - 鏈表:線性表的鏈式表示,不要求存儲地址聯繫,失去了隨機訪問的特性。適合插入刪除。單鏈表、雙鏈表、循環鏈表、靜態鏈表。
- 單鏈表:鏈表結點存放後繼指針。訪問後繼結點時間複雜度爲O(1),前驅爲O(n)。
- 雙鏈表:鏈表結點存放前驅和後繼指針,這樣就克服了單鏈表不能從後往前遍歷的缺陷。prior、next
- 循環鏈表:循環單鏈表、循環雙鏈表。循環單鏈表需要將尾結點指針指向頭結點,這樣就可以形成環。循環雙鏈表還需要將頭結點的prior指針指向尾結點。
- 靜態鏈表:藉助數組實現的鏈表。
- 線性表基本操作:創銷、CRUD、判空、判表長、輸出。
- 線性結構和非線性結構區別:線性結構除第一個和最後一個節點外,其餘結點有唯一前驅和後繼,第一個節點無前驅,最後一個結點無後繼,結點之間是一對一關係。非線性結構結點前驅後繼不具有唯一性,結點之間關係爲一對多或者多對多。
- 順序存儲結構特點:存儲密度大,空間利用率高;隨機訪問,隨機存取;不適合插入刪除操作,因爲需要移動大量元素;預分配存儲空間難以確定。
- 順序存儲結構與鏈式存儲結構比較
順序存儲結構 | 鏈式存儲結構 | |
---|---|---|
優點 | 存儲密度高、隨機訪問、隨機存取 | 插入刪除方便、動態分配存儲空間 |
缺點 | 不適合插入刪除,因爲需要移動大量元素;預分配存儲空間難以確定 | 存儲密度小、訪問需要從頭遍歷鏈表 |
- 順序表和鏈表的比較
區別 | 順序表 | 鏈表 |
---|---|---|
存儲結構 | 順序存儲 | 鏈式存儲 |
存取/訪問速率 | 隨機存取,隨機訪問,方便O(1) | 不方便,需要遍歷O(n) |
存儲密度 | 高 | 低 |
插入刪除 | 不方便,需要移動大量元素 | 方便,修改指針 |
- 數組和鏈表的比較
區別 | 數組 | 鏈表 |
---|---|---|
分配空間 | 靜態分配/棧分配 | 動態分配/堆分配 |
訪問速率 | 根據數組下標直接訪問 | 從頭遍歷 |
插入刪除 | 不方便,需要移動大量元素 | 方便,只需修改指針 |
- 頭指針和頭結點區分
區分 | 頭指針 | 頭結點 |
---|---|---|
概念 | 指向鏈表第一個結點的指針 | 帶頭結點鏈表的第一個結點,是鏈表在表頭附加的結點 |
是否必須 | 是 | 否,只是爲了統一操作 |
引入頭結點作用 | 頭指針就是鏈表名字、標記鏈表 | 空表非空表頭結點都指向頭結點/統一了第一個數據結點和其餘結點的操作 |
- 單鏈表雙鏈表的區別
單鏈表 | 雙鏈表 |
---|---|
存放後繼指針next ,只能從前往後遍歷 | 存放前驅後繼指針prior、next,雙向遍歷 |
受限線性表/特殊線性表(棧、隊列、串)
- 棧:限定表尾插入刪除,順序棧、鏈棧、共享棧。
- 順序棧:棧的順序表示。
- 鏈棧:棧的鏈式存儲。
- 共享棧兩個棧共享同一片空間。
- 隊列:一段插入、一段刪除,順序隊列(循環隊列)、鏈隊、雙端隊列。
- 循環隊列:把順序隊列的尾指針指向頭結點形成環。
- 鏈隊:隊列鏈式存儲。
- 雙端隊列:兩端都可以插入刪除的隊列。
- 輸入受限的雙端隊列:只允許一端插入,兩端刪除。
- 輸出受限的雙端隊列:只允許一端刪除,兩端插入。
- 串:限制數據元素爲字符的線性表。
- 串的存儲結構:定長順序存儲、堆分配、塊鏈存儲。
- 串的模式匹配暴力匹配算法、KMP、改進KMP。
- 順序隊列相比,循環隊列有哪些優點?解決假溢出現象。
- 棧的應用:括號匹配、表達式求值、遞歸。
- 隊列應用:圖的廣度優先遍歷,樹的層次遍歷,FCFS先來先服務。
- 多棧共享技術:兩棧共享空間、利用“棧底位置不變、棧頂動態變化”特性。
- 串和線性表的區別?串是特殊線性表,限制數據元素爲字符,並且串的操作和線性表有較大差別,線性表操作大多以數據元素爲操作對象,而串大多以串的整體或模式串作爲操作對象。
- 簡述KMP算法
KMP算法是在簡單模式匹配算法的基礎上對串的模式匹配進行優化。也就說KMP是改進的暴力匹配算法。
主要的思路是每趟比較過程中讓子串先滑動到一個合適的位置。
當發生不匹配時,不同於簡單模式匹配的右移一位,而是移動到適合的位置。
這裏所移動的位置依靠NEXT[]數組,求next[]數組的方法是比較前後綴相同元素。 - 棧和隊列區別
棧 | 隊列 |
---|---|
先入後出 | 先入先出 |
只許表尾插入刪除 | 一段插入一段刪除 |
線性表推廣(數組、廣義表)
- 數組:相同數據類型的數據元素的有限序列。
- 矩陣:二位數組即矩陣,數組可以是數字、字符等,矩陣數據元素只能是數字。對稱矩陣、對角矩陣、三角矩陣、三對角矩陣、稀疏矩陣。按行優先存儲、按列優先存儲。
- 壓縮存儲:相同數值分配一個存儲空間、零不分配存儲空間,目的節約存儲空間。
- 稀疏矩陣:絕大部分數據元素爲0的矩陣,通過三元組壓縮存儲。但壓縮存儲後失去了隨機存取的特性。稀疏矩陣的三元組既可以採用數組存儲,也可以採用十字鏈表存儲。
- 廣義表:放鬆了對錶元素原子性的限制,容許表元素有自身結構。
樹
- 二叉樹:結點的度最多爲二,有左右子樹之分。
- 完全二叉樹:結點從上到下,從左到右。
- 滿二叉樹:每一層結點數都達到最大值。特殊的完全二叉樹。
- 二叉排序樹BST:左子樹所有結點值小於根值,右大於根,也可以爲空樹。
- 平衡二叉樹AVL:改進的二叉排序樹,平衡因子不大於1。
- 平衡調整:LL調整、RR調整、LR調整、RL調整。
- B-樹:平衡二叉樹擴展,結點多關鍵字的平衡樹。
- B+樹:B-樹的變形,葉子結點存儲關鍵字以及記錄地址,非葉子結點只有索引作用。
- B-樹和B+樹區別:B-樹分支從關鍵字兩端引出、B+樹分支從關鍵字引出;B-樹中每個結點都存儲信息,B+樹只有根節點存儲關鍵字和記錄,非葉結點只有索引作用,另外B+樹可以用指針指向關鍵字最小的結點,並把所有結點鏈接成單鏈表。
- 哈夫曼樹:樹的帶權路徑長度最小的二叉樹,也稱最優二叉樹。
- 遍歷二叉樹:按某種搜索路徑尋訪二叉樹每個結點,使得每個結點只被訪問一次。
- 線索二叉樹:可以像遍歷單鏈表一樣遍歷二叉樹,加快查找前驅和後繼結點。
- 二叉樹存儲結構:順序存儲結構、鏈式存儲結構;完全二叉樹和滿二叉樹採用順序存儲,其他二叉樹如需要順序存儲需要添加空結點,一般二叉樹採用鏈式存儲結構。
- 樹的三種存儲方法:孩子表示法、雙親表示法、孩子兄弟表示法。
- 樹的遍歷:先序遍歷,後續遍歷
- 二叉樹遍歷:先序遍歷,中序遍歷,後續遍歷,層次遍歷
- 樹、森林、二叉樹的轉換:左孩子右兄弟
- 樹的應用-並查集:管理一些不相交集合,並支持兩種操作,合併和查詢,其重要思想在於用集合中一個元素代表整個集合。
- 簡述哈夫曼樹:主要內容分爲概念、性質、構造、哈夫曼編碼、平均碼長、作用。
概念:哈夫曼樹是WPL最小的二叉樹,也稱最優二叉樹。
性質:離根越近結點權值越大,沒有度爲1的結點,原結點都是葉子結點,結點總數2n-1,度爲二的結點數爲n-1。
構造:將集合中兩個權值最小的結點相加結合生成一個新節點,放入集合,把原來的兩個結點刪除,在找兩個最小的結點重複進行。
哈夫曼編碼:可變長最短前綴編碼。
平均碼長:各初始結點權值乘路徑長度的總和。
作用:數據壓縮
圖
- 有向邊、無向邊:有向邊是弧,無向邊是邊。
- 完全圖:該有的邊都有,有向完全圖邊的個數爲n(n-1),無向完全圖邊的個數爲n(n-1)/2。
- 簡單圖,多重圖:是否有自環和平行邊。
- 連通圖、強連通圖:有向圖任意兩個頂點都有路徑相通,無向圖任意兩點之間都有來回路徑。
- 極大連通子圖、極小連通子圖、極大強連通子圖、極小強連通子圖:極大連通子圖即連通分量,極小連通子圖即邊最少的連通子圖,極大強連通子圖即強連通分量、極小強連通子圖在保持任意兩結點來回互通的情況下弧最少的連通子圖。
- 生成樹:無向圖的一個極小連通子圖。
- 圖的遍歷:從某一頂點按需訪問圖中所有結點,每個結點只被訪問一次。
- DAG:有向無環圖,包括AOE和AOV。
- AOE:以弧爲活動,頂點表示事件的有向網。邊有權值,用於關鍵路徑。
- AOV:以頂點表示活動、弧表示事件的有向網。邊無權值,用於拓撲排序。
- 圖的存儲結構:鄰接矩陣、鄰接表、十字鏈表、鄰接多重表。
- 鄰接矩陣:適用於稠密圖,無向圖對稱矩陣,有向圖不是對稱矩陣。包含頂點集和邊集。
- 鄰接表:適用於稀疏圖,通過頂點表和邊表組成。頂點表順序,邊錶鏈式。有向圖鄰接表和逆鄰接表的結合。
- 十字鏈表:適用於有向圖,對鄰接表查找入度的改進,方便快速查找入度。
- 鄰接多重表:適用於無向圖,對鄰接表刪除一個結點需要刪除兩個邊表結點。
- 圖的遍歷:深度優先遍歷DFS、廣度優先遍歷BFS。
- DFS:類似於樹的先序遍歷。工作棧實現,從初始點v開始訪問任意一個未被訪問的鄰接頂點m1,頂點m1訪問一個未被訪問的鄰接頂點m2,依次進行同樣操作,直到該頂點沒有未被訪問的鄰接頂點,則返回上一層,重複操作。
- BFS:類似於樹的層次遍歷。隊列+輔助數組,從初始點出發,訪問所有鄰接頂點m1,m2…然後依次訪問m1未被訪問的鄰接頂點,m2未被訪問的鄰接頂點…重複上述操作。
- 最小生成樹:無向網中邊權值之和最小的生成樹,最小生成樹MST不一定唯一。prim、克魯斯卡爾。
- Prim:從點找邊,先將初始點放入結果集,從初始頂點出發找到一個未被訪問的權值最小的邊所鄰接的頂點,放入結果集,然後再找和這兩個頂點未被訪問的權值最小邊所鄰接頂點,放入集合,依次進行。
- 克魯斯卡爾:從邊找點,先找一個權值最小的邊,然後找與這個邊上頂點所鄰接的最小邊,這之間不能形成環,依次進行。
- 最短路徑:迪傑斯特拉、弗洛伊德。
- 克魯斯卡爾:求單源最短路徑。
- 弗洛伊德Floyd:求各頂點之間的最短路徑。
- 拓撲結構:將入度爲0的頂點取出,可用於檢測AOV網是否有環。
- 關鍵路徑:在AOE網中,從源點到匯點的最長路徑。
查找
- 查找分類:
按功能:靜態查找表適合查詢,如順序查找,折半查找;動態查找表適合插入刪除,如BST、AVL、B-樹、B+樹。
按結構:線性表、樹表、散列表。 - 查找表:同一類型數據元素的集合。
- 線性表查找:順序查找、折半查找、分塊查找。
- 順序查找:可以對有序表、也可以無序表。適用於順序和鏈式存儲。
- 折半查找:對有序表的查找。用到折半查找判定樹。適用於順序存儲。
- 分塊查找:順序查找和折半查找的結合,塊內無序、塊間有序。
- 樹表查找:二叉排序樹、平衡二叉樹、B-樹、B+樹。
- 二叉排序樹:可以爲空樹,當有左子樹,左子樹所有結點的值小於根結點的值,若有右子樹,則右子樹上結點的值大於根值,左子樹,右子樹同理。
- 平衡二叉樹:二叉排序樹的改進,還要求平衡因子不大於1。
- 關鍵字:數據元素中某個數據項的值,用它可以標識一個數據元素。
- B-樹:平衡二叉樹的推廣,多關鍵字平衡樹。
- B+樹:B-樹變形,葉子結點存放關鍵字和記錄地址,非葉子結點只有索引作用,且可以用一個指針指向最小關鍵字的葉子結點,把各葉子結點鏈接成單鏈表。
- 散列表:根據關鍵字直接進行訪問的數據結構,建立了關鍵字和物理存儲的直接映射。
- 散列函數:把關鍵字映射成物理地址的函數。
- 散列函數構造方法:直接定址法、平方取中法、初留取餘法、數字分析法、疊加法。
- 衝突:不同關鍵之映射到同一地址的情況。
- 解決衝突的方法:解決衝突的方法就是解決增量序列的問題。
開放定址法:線性探查發、平方探查發、再散列法、僞隨機法。不適用於刪除,因爲刪除的數據元素存儲位置爲空,他後面的數據元素就無法遍歷查詢到了。平方取中法解決了線性探查發堆積現象。
拉鍊法:通過鏈表把映射到相同地址的關鍵字鏈接存儲。適用於插入刪除。 - 散列查找效率影響因素:填裝因子,散列函數,處理衝突的方法。平均查找長度ASL依賴於填裝因子。填裝因子是所存儲的數據元素和整個申請存儲空間的比值,即表的裝滿程度。
- 各查找方法的基本思想以及ASL:
順序查找:給定的關鍵字k從前往後對比線性表中記錄的關鍵字,如果該機率關鍵字等於k,則查找成功,否則查找失敗。ASL=3(n+1)/4
折半查找:將給定的關鍵字和表中中間記錄關鍵字比較,如相等則成功,若小於中間關鍵字則說明要查找的關鍵字在表的前半部分,若大於同理,如此進行,直達找到,查找成功,否則查找失敗。ASL=log2 (n+1)-1
分塊查找:順序查找或折半查找索引表、順序查找塊內元素。
散列查找:通過散列函數求關鍵字存儲地址,看是否爲空,如果空就失敗,否則比較該記錄關鍵字,若採用開放定址法則若不等則通過增量序列找到下一個存儲地址進行對比,若拉鍊法,遍歷查找鏈表。
排序
- 算法評價:時間空間複雜度、穩定性。
- 內部排序、外部排序:內部排序利用內存;外部排序內存+外存,適用於大文件。
- 排序種類:
插入排序:直接插入排序、希爾排序
交換排序:冒泡排序、快速排序
選擇排序:直接選擇排序、堆排序
歸併排序:二路歸併,多路歸併排序(外排序)
基數排序、計數排序、桶排序
- 排序算法穩定性:相同數字在排序前後相對位置不變。
不穩定:希爾排序、快速排序、直接選擇排序、堆排序
不穩定:直接選擇排序、冒泡排序、歸併排序、基數排序、計數排序、桶排序 - 排序算法時間複雜度:
T(n)=O(n^2)直接插入排序、直接選擇排序、冒泡排序
T(n)=O(nlog2 n)希爾排序、快速排序、堆排序、歸併排序
T(n)=O(n)基數排序、計數排序、桶排序 - 排序算法空間複雜度:
S(n)=O(1)直接插入排序、希爾排序、冒泡排序、直接插入排序、堆排序
S(n)=O(log2 n)快速排序
S(n)=O(n)歸併排序
S(n)=O( r)基數排序
- 直接插入排序:和打撲克牌一樣,把未排序的部分按序取出一個元素插入到已經排序好的有序序列中,插入位置從前往後找。時間複雜度O(n^2),空間複雜度O(1)
- 希爾排序:分組直接插入排序,將排序元素按增量序列分爲幾組,組內直接插入排序,縮減增量,使得元素基本有序,在進行一次直接插入排序。時間複雜度O(nlog2 n),空間複雜度O(1)
- 冒泡排序:比較相鄰元素的值。時間複雜度O(n^2),空間複雜度O(1)
- 快速排序:從左到右的元素都能一次性找到自己最終位置。piovt基準,low,high。時間複雜度O(nlog2 n),空間複雜度O(log2 n)
- 直接選擇排序:在給定的一組記錄中選擇最小的和第一個記錄交換,然後從第二個記錄到最後記錄中找最小的和第二個記錄交換,如此下去。方式可選小放前面、選大放後面。時間複雜度O(n^2),空間複雜度O(1)
- 堆排序:大根堆、小根堆。時間複雜度O(nlon2 n),空間複雜度O(1)
- 二路歸併排序:兩兩歸併,排序成一個個有序序列。時間複雜度O(nlog2 n),空間複雜度O(n)
- 基數排序:實現方法爲最高位優先、最低爲優先。利用輔助隊列按位收集和分配。時間複雜度O(n),空間複雜度O(r )