讀書筆記_算法第四版(二)

算法第四版(謝路雲譯)

官方網站:http://algs4.cs.princeton.edu/home/有部分源代碼和部分課後習題答案。

個人練習代碼:https://github.com/morefans/AlgorithmsFourthEdition

 

第4章 圖

4.1 無向圖

l  圖是由一組頂點和一組能夠將兩個頂點相連的邊組成的。

l  自環:即一條連接一個頂點和其他自身的邊。平行邊:連接同一對頂點的兩條邊。多重圖:含有平行邊的圖。簡單圖:沒有平行邊或自環的圖。

l  路徑,簡單路徑,簡單環,路徑或環的長度,連通,連通圖。樹是無環連通圖。森林,連通圖的生成樹,生成樹森林。

l  度數:某個頂點的度數就是依附於它的邊的總數。圖的密度,稀疏圖,稠密圖,二分圖。

l  圖的表示應該滿足:它必須爲可能在應用中碰到的各種類型的圖預留出足夠的空間;實例方法的實現一定要快。待選:鄰接矩陣(空間不能滿足且不能表示平行邊),邊的數組(簡單但是不快),鄰接表數組(滿足條件)。

l  深度優先搜索:深度優先搜索標記與起點連通的所有頂點所需的時間和頂點的度數之和成正比,和路徑的長度成正比。(小巧而又強大的算法)

l  Tremaux搜索(走迷宮)。

l  廣度優先遍歷:解決單點最短路徑問題。(所需的時間在最壞情況下和V+E成正比)

l  對於從s可達的任意頂點v,廣度優先搜索都能找到一條從s到v的最短路徑(沒有其他從s到v的路徑所含的邊比這條路徑更少)。

l  深度優先搜索的與預處理使用的時間和空間與V+E成正比且可以在常數時間內處理關於圖的連通性查詢。

l  解決圖連通性問題時union-find算法其實更快,因爲不需要對圖進行預處理,因此在完成只需要判斷連通性或是需要完成有大量連通性查詢和插入操作混合等類似的任務時,更傾向使用union-find算法。

l  檢測環:給定的圖是否含有環。

l  雙色問題:給定圖是否是二分圖。

l  以下爲“答疑”和“練習”中的知識點:

l  不把所有的算法都實現在Graph.Java中是避免寬接口。

l  頂點v的離心率是它和離它最遠的頂點的最短距離。圖的直徑即所有頂點的最大離心率,半徑爲所有頂點的最小離心率,中心爲離心率和半徑相等的頂點。圖的周長是圖中最短環的長度,如果是無環圖,則它的周長爲無窮大。

l  歐拉環:圖中經過每條邊一次且僅一次的環。哈密爾頓環是指不重複地走過所有的點,並且最後還能回到起點的迴路。

4.2 有向圖

l  有向圖:由一組頂點和一組有方向的邊組成的,每條有方向的邊都連接着有序的一對頂點(頂點分別稱爲頭和尾)。

l  單點可達性:是否存在一條從s到給定頂點v的有向路徑。多點可達性:是否存在一條從集合中的任意頂點到達給定頂點v的有向路徑。在有向圖中,深度優先搜索標記由一個集合的頂點可達的所有頂點所需的時間與被標記的所有頂點的出度之和成正比。

l  單點有向路徑,單點最短有向路徑。優先級限制下的調度問題。拓撲排序:給定一幅有向圖,將所有的頂點排序,使得所有的有向邊均從排在前面的元素指向排在後面的元素(或者說明無法做到這一點)。拓撲排序典型應有:任務調度,課程安排,繼承,電子表格,符號鏈接。

l  如果一個有優先級限制的問題中存在有向環,那麼這個問題一定是無解的。有向無環圖(DAG):就是一幅不含有向環的有向圖。

l  當且僅當一幅有向圖是無環圖時它才能進行拓撲排序。一幅有向無環圖的拓撲排序即爲所有頂點的逆後序排列。使用深度優先搜索對有向無環圖進行拓撲排序所需的時間和V+E成正比。

l  解決任務調度類應用通常需要以下三步:指明任務和優先級條件;不斷檢測並去除有向圖中的所有環以確保存在可行方案;使用拓撲排序解決調度問題。

l  強連通:兩個頂點互相可達。強連通圖:一幅有向圖中任意兩個頂點都是強連通的。強連通性具有:自反性,對稱性,傳遞性。

l  Kosaraju算法:高效計算強連通分量。使用深度優先查找給定有向圖G的方向圖GR,根據由此得到的所有頂點的逆後序再次深度優先搜索處理有向圖G(Kosaraju算法),其構造函數中的每一次遞歸調用所標記的頂點都在同一個強連通分量之中。Kosaraju算法的預處理所需的時間和空間與V+E成正比且支持常數時間的有向圖強連通性的查詢。

4.3 最小生成樹

l  加權圖:是一種每條邊關聯一個權值或是成本的圖模型。

l  圖的生成樹:是它的一棵含有其所有頂點的無環連通子圖。

l  一幅加權圖的最小生成樹(MST)是它的一棵權值(樹中所有邊的權值之和)最小的生成樹。

l  一些約定:只考慮連通圖(非連通圖不存在最小生成樹,只有最小生成森林);邊的權重不一定表示距離;邊的權重也可能是0或者負數(邊權重都爲正數的話最小生成樹定義爲連接所有頂點且總權重最小的子圖就足夠了);所有邊的權重都各不相同(若權重可以相同那麼最小生成樹就不一定是唯一的了,但這個假設並不會限制算法的適用範圍)。

l  圖的一種切分是將圖的所有頂點分爲兩個非空且不重疊的兩個集合。橫切邊是一條連接兩個屬於不同集合的頂點和邊。

l  切分定理:在一幅加權圖中,給定任意的切分,它的橫切邊中的權重最小者必然屬於圖的最小生成樹。

l  最小生成樹的貪心算法:下面這種方法會將含有V個頂點的任意加權連通圖中屬於最小生成樹的邊標記爲黑色:初始狀態下所有邊均爲灰色,找到一種切分它產生的橫切邊均不爲黑色,將它權重最小的橫切邊標記爲黑色,反覆,知道標記了V-1條黑色邊爲止。

l  Prim算法:計算最小生成樹的方法,它的每一步都會爲一棵生長中的樹添加一條邊,一開始這棵樹只有一個頂點,然後會向它添加V-1條邊,每次總是將下一條連接樹中的頂點與不在樹中的頂點且權重最小的邊(黑色表示)加入樹中(即由樹中的頂點所定義的切分中的一條橫切邊)。能夠計算任意加權連通圖的最小生成樹。

l  Prim算法的延時實現計算一幅含有V個頂點和E條邊的連通加權無向圖的最小生成樹所需的空間與E成正比,所需的時間與ElogE成正比(最壞情況)。

l  Prim算法的即時實現計算一幅含有V個頂點和E條邊的連通加權無向圖的最小生成樹所需空間和V成正比,所需的時間和ElogV成正比(最壞情況)。

l  Kruskal算法:按照邊的權重順序(從小到大)處理它們,將邊加入最小生成樹中(圖中的黑色邊),加入的邊不會與已經加入的邊構成環,直到樹中含有V-1條邊爲止。這些黑色的邊逐漸由一片森林合併爲一棵樹,也就是圖的最小生成樹。Kruskal算法能能夠計算任意加權連通圖的最小生成樹。

l  Kruskal算法的計算一幅含有V個頂點和E條邊的連通加權無向圖的最小生成樹所需的空間和E成正比,所需的時間和ElogE成正比(最壞情況)。

l  Prim算法和Kruskal算法不能處理有向圖處理問題。有向圖更難,稱爲最小樹形圖問題。

4.4 最短路徑

l  在一幅加權有向圖中,從頂點s到頂點t的最短路徑是所有從s到t的路徑中的權重最小者。

l  最短路徑的性質:路徑是有向的;權重不一定等價於距離;並不是所有頂點就是可達的;負權重會使問題更復雜;最短路徑一般都是簡單的;最短路徑不一定是唯一的;可能存在平行邊和自環。

l  最短路徑樹:給定一幅加權有向圖和一個頂點s,以s爲起點的一棵最短路徑樹是圖的一幅子圖,它包含s和從s可達的所有頂點。這棵有向樹的根結點爲s,樹的每條路徑都是有向圖中的一條最短路徑。

l  放鬆操作(relax):放鬆邊v->w意味着檢查從s到w的最短路徑是否是先從s到v,然後再由v到w。如果是,則根據這個情況更新數據結構的內容。由v到達w的最短路徑是distTo[v]與e.weight()之和,如果這個值不小於distTo[w],稱這條邊失效了並將它忽略,如果這個值更小就更新數據。(鬆弛術語來源於橡皮筋比喻:放鬆一條邊就像將橡皮筋轉移到一條更短的路徑上,從而緩解了橡皮筋的壓力)

l  最短路徑的最優性條件:令G爲一幅加權有向圖,頂點s是G中的起點,distTo[]是一個由頂點索引的數組,保存的是G中路徑的長度,對於從s可達的所有頂點v,distTo[v]的值是從s到v的某條路徑的長度,對於從s不可達的所有頂點v,該值爲無窮大。當且僅當對於從v到w的任意一條邊e,這些值都是滿足distTo[w]<=distTo[v]+e.weight()時(換句話說,不存在有效邊時),它們是最短路徑的長度。

l  通用最短路徑算法:將distTo[s]初始化爲0,其他distTo[]元素初始化爲無窮大,繼續如下操作:放鬆G中的任意邊,直到不存在有效邊爲止。對於任意從s可達的頂點w,在進行這些操作之後,distTo[w]的值即爲從s到w的最短路徑的長度(且edgeTo[w]的值即爲該路徑上的最後一條邊)。

l  Dijkstra算法:首先將distTo[s]初始化爲0,distTo[]中的其他元素初始化爲正無窮,然後將distTo[]最小的非樹頂點放鬆並加入樹中,如此這般,直到所有的頂點都在樹中或者所有的非樹頂點的distTo[]值均爲無窮大。Dijkstra算法能夠解決邊權重非負的加權有向圖的單起點最短路徑問題。

l  在一幅含有V個頂點和E條邊的加權有向圖中,使用Dijkstra算法計算根結點爲給定起點的最短路徑樹所需的空間與V成正比,時間與ElogV成正比(最壞情況下)。

l  無環加權有向圖中的最短路徑算法:能夠在線性時間內解決單點最短路徑問題;能夠處理負權重的邊;能夠解決相關的問題,例如找出最長的路徑。

l  按照拓撲排序放鬆頂點,就能在和E+V成正比的時間內解決無環加權有向圖的單點最短路徑問題。

l  解決無環加權有向圖中的最長路徑問題所需的時間與E+V成正比。

l  解決並行任務調度問題的關鍵路徑方法的步驟如下:創建一幅無環加權有向圖,其中包含一個起點s和一個重點t且每個任務都對應着兩個頂點(一個起始頂點和一個結束頂點)。對於每個任務都有一條從它的其實頂點指向結束頂點的邊,邊的權重爲任務所需的時間。對於每條優先級限制v->w添加一條從v的結束頂點指向w的起始頂點的權重爲0的邊。我們還需要爲每個任務添加一條從起點指向該任務的其實頂點的權重爲0的邊以及一條從該任務的結束頂點到終點的權重爲0的邊。這樣每個任務預計的開始時間即爲從起點到它的起始頂點的最長距離。

l  解決優先級限制下的並行任務調度問題的關鍵路徑算法所需的時間爲線性級別。

l  相對最後期限限制下的並行任務調度問題是一個加權有向圖中的最短路徑問題(可能存在環和負權重邊)。

l  負權重環:加權有向圖中的負權重環是一個總權重(環上的所有邊的權重之和)爲負的有向環。(繞着這個環一直轉圈子就能將總權重降到任意小的權重值)

l  當且僅當加權有向圖中至少存在一條從s到v的有向路徑且所有從s到v的有向路徑上的任意頂點都不存在與任何負權重環中時,s到v的最短路徑纔是存在的。

l  Bellman-Ford算法:在任意含有V個頂點的加權有向圖中給定起點s,從s無法到達任何負權重環,以下算法能夠解決其中的單點最短路徑問題:將distTo[s]初始化爲0,其他distTo[]元素初始化爲無窮大,以任意順序放鬆有向圖的所有邊,重複V輪。Bellman-Ford算法所需的時間和EV成正比,空間和V成正比;

l  套匯問題等價於加權有向圖中的負權重環的檢測問題。

第5章 字符串

l  字符,不可變性,索引,長度,子字符串,字符串的連接,字符數組,字符索引數組,數字。

5.1 字符串排序

l  低位優先(Least-Significant-Digit-First):從右到左檢查鍵中的字符,最適合用於鍵長度都相同的字符串排序應用。

l  高位優先(Most-Significant-Digit-First):從左到右檢查鍵中的字符。

l  鍵索引計數法:適用於小整數鍵的簡單排序方法。鍵索引計數法排序N個鍵爲0到R-1之間的整數的元素需要訪問數組11N+4R+1次。

l  低位優先的字符串排序算法能夠穩定地將定長字符串排序。

l  對於基於R個字符的字母表的N個以長爲W的字符串爲鍵的元素,低位優先的字符串排序需要訪問~7WN+3WR次數組,使用的額外空間與N+R成正比。

l  高位優先的字符串排序對字符串末尾處理需要特別注意,小型子數組切換到插入排序是必要的,含有大量等值鍵的子數組排序會比較慢。

l  要將基於大小爲R的字母表的N個字符串排序,高位優先的字符串排序算法平均需要檢查NlogRN個字符;訪問數組的次數在8N+3R到~7wN+3wR之間,其中w是字符串的平均長度;最壞情況下高位優先的字符串排序算法所需的空間與R乘以最長的字符串的長度之積成正比(再加上N)。

l  三向字符串快速排序:根據高位優先的字符串排序算法改進快速排序,根據鍵的首字母進行三向切分,僅在中間子數組中的下一個字符(因爲鍵的首字母都與切分字符相等)繼續遞歸排序。要將含有N個隨機字符串的數組排序,三向字符串快速排序平均需要比較字符~2NlnN次。

5.2 單詞查找樹

l  值爲空的結點在符號表中沒有對應的鍵,它們的存在是爲了簡化單詞查找樹中的查找操作。

l  R向單詞查找樹:基於含有R個字符的字母表的單詞查找樹。結點保存一個value值爲從根結點到該結點合起來的字符串,保存一個大小爲R的子鏈接數組。

l  單詞查找樹的鏈表結構(形狀)和鍵的插入或刪除順序無關:對於任意給定的一組鍵,其單詞查找樹都是唯一的。

l  在單詞查找樹中查找一個鍵或者插入一個鍵時,訪問數組的次數最多爲鍵的長度加1。

l  字母表的大小爲R,在一棵由N個隨機鍵構造的單詞查找樹中,未命中查找平均所需檢查的結點數量爲~logRN。

l  一棵單詞查找樹中的鏈接總數在RN到RNw之間,其中w爲鍵的平均長度。(當所有鍵均較短時鏈接總數接近於RN;當所有鍵均較長時鏈接總數接近於RNw;縮小R能節省大量的空間)

l  單向分支:解決長尾巴問題。

l  三向單詞查找樹:每個結點含有一個字符、三條鏈接和一個值,三條鏈接對應當前字母小於等於大於結點字母的所有鍵。

l  由N個平均長度爲w的字符串構造的三向單詞查找樹中的鏈接總數在3N到3Nw之間。

l  在一棵由N個隨機字符串構造的三向單詞查找樹中,查找未命中平均需要比較字符~lnN次。除~lnN次外,一個插入或命中的查找會比較一次被查找的鍵中的每個字符。

l  三向單詞查找樹最大好處是它能夠很好地適應實際應用中可能出現的被查找鍵的不規則性。(實際應用中的鍵來自大型字母表而各字符使用非常不均衡,且實際應用程序中的鍵常常有着類似的結構)

l  由N個隨機字符串構造的根結點進行了Rt向分支且不含有外部單向分支的三向單詞查找樹中,一個插入或查找操作平均需要進行約lnN-tlnR次字符比較。

5.3 子字符串查找

l  暴力子字符串查找算法:用一個指針i跟蹤文本,一個指針j跟蹤模式。最壞情況下,其在長度爲N的文本中查找長度爲M的模式需要~NM次字符比較。

l  Knuth-Morris-Pratt子字符串查找算法(KMP算法):主要思想是提前判斷如何重新開始查找,這種判斷只取決於模式本身。

l  對於長度爲M的模式字符串和長度爲N的文本,KMP字符串查找算法訪問的字符不會超過M+N個。

5.4 正則表達式

l   

5.5 數據壓縮

l  數據壓縮的基礎模型(兩個能夠讀寫比特流的黑盒子):1、壓縮盒,能夠將一個比特流B轉化爲壓縮後的版本C(B)。2、展開盒,能夠將C(B)轉化回B。(無損壓縮模型)

l  不存在能壓縮任意比特流的算法。

l  遊程編碼:一長串重複的比特,用前4位表示長度,然後是0或者1。典型應用爲位圖的無損壓縮。隨着分辨率的提高遊程編碼的效果會大大提高。

l  霍夫曼壓縮(Huffman)(變長前綴碼):所有字符編碼都不會稱爲其他字符編碼的前綴,便是前綴碼(不需要分隔符)。霍夫曼壓縮不僅對於自然語言而且對各種來誒性的文件都有效果。

l  對於任意前綴碼,編碼後的比特字符串的長度等於相應單詞查找樹的加權外部路徑。加權外部路徑長度是所有葉子的權重(頻率)和深度之積的和。

l  給定一個含有r個字符的集合和它們的頻率,霍夫曼算法所構造的前綴碼是最優的。

l  LZW壓縮算法:

第6章 背景

 

6.2 B-樹

l  B-樹的成本模型:我們使用頁的訪問次數(無論讀寫)作爲外部查找算法的成本模型。這裏用來泛指基於固定頁大小的多向平衡查找樹的數據結構。

l  一棵M階B-樹(M爲正偶數)或者僅是一個外部k-結點(含有k個鍵和相關信息的樹),或者由若干內部k-結點(每個結點都含有k個鍵和k條鏈接,鏈接指向的子樹表示了鍵之間的間隔區域)組成,它的結構性質如下:從根結點到每個外部結點的路徑長度均相同(完美平衡);對於根結點,k在2到M-1之間,對於其他結點k在M/2到M-1之間。

l  含有N個元素的M階B-樹中的一次查找或插入操作需要logMN~logM/2N次探查,在實際情況下這基本是一個常數。

6.4 網絡流算法

l  一個流量網絡是一張邊的權重(這裏稱爲容量)爲正的加權有向圖。一個st-流量網絡有兩個已知的頂點,即起點s和終點t。

l  st-流量網絡中的st流量配置是由一組和每條邊相關聯的值組成的集合,這個值被稱爲邊的流量。如果所有邊的流量均小於邊的容量且滿足每個頂點的局部平衡(即流入量等於流出量,淨流量爲0,s和t除外),那麼久稱這種流量配置方案是可行的。

l  最大st-流量:給定一個st-流量網絡,找到一種st-流量配置,使得從s到t的流量最大化。

l  Ford-Fulkerson最大流量算法(增廣路徑算法):網絡中的初始流量爲0,沿着任意從起點到終點(且不含有飽和的正向邊或是空逆向邊)的增廣路徑增大流量,直到網絡中不存在這樣的路徑爲止。

l  未完。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章