1. 程式人生 > >圖解常用算法

圖解常用算法

strong 方便 gif dfs rst 適用於 指向 生成 屬於

我們經常會用到一些算法,而大部分算法過於抽象,記憶起來比較困難,而使用圖解可以幫助我們更好地理解和記憶這些算法。

一、深度優先搜索算法(DFS)

深度優先搜索算法(Depth-First-Search),是搜索算法的一種。它是圖論中的經典算法,利用深度優先搜索算法可以產生目標圖的相應拓撲排序表,利用拓撲排序表可以方便的解決很多相關的圖論問題,如最大路徑問題等等。一般用堆數據結構來輔助實現 DFS 算法。DFS 屬於盲目搜索。

深度優先遍歷圖算法步驟:

1. 訪問頂點 v;

2. 依次從 v 的未被訪問的鄰接點出發,對圖進行深度優先遍歷;直至圖中和 v 有路徑相通的頂點都被訪問;

3. 若此時圖中尚有頂點未被訪問,則從一個未被訪問的頂點出發,重新進行深度優先遍歷,直到圖中所有頂點均被訪問過為止。

上述描述可能比較抽象,舉個實例:

DFS 在訪問圖中某一起始頂點 v 後,由 v 出發,訪問它的任一鄰接頂點 w1;再從 w1 出發,訪問與 w1 鄰接但還沒有訪問過的頂點 w2;然後再從 w2 出發,進行類似的訪問,…如此進行下去,直至到達所有的鄰接頂點都被訪問過的頂點 u 為止。

接著,退回一步,退到前一次剛訪問過的頂點,看是否還有其它沒有被訪問的鄰接頂點。如果有,則訪問此頂點,之後再從此頂點出發,進行與前述類似的訪問;如果沒有,就再退回一步進行搜索。重復上述過程,直到連通圖中所有頂點都被訪問過為止。

二、廣度優先搜索算法(BFS)

廣度優先搜索算法(Breadth-First-Search),是一種圖形搜索算法。簡單的說,BFS 是從根節點開始,沿著樹 (圖) 的寬度遍歷樹 (圖) 的節點。如果所有節點均被訪問,則算法中止。BFS 同樣屬於盲目搜索。一般用隊列數據結構來輔助實現 BFS 算法。

算法步驟:

1. 首先將根節點放入隊列中。

2. 從隊列中取出第一個節點,並檢驗它是否為目標。

如果找到目標,則結束搜尋並回傳結果。

否則將它所有尚未檢驗過的直接子節點加入隊列中。

3. 若隊列為空,表示整張圖都檢查過了——亦即圖中沒有欲搜尋的目標。結束搜尋並回傳「找不到目標」。

4. 重復步驟 2。

技術分享

三、歸並排序算法

歸並排序(Mergesort,臺灣譯作:合並排序)是建立在歸並操作上的一種有效的排序算法。該算法是采用分治法(DivideandConquer)的一個非常典型的應用。

算法步驟:

1. 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合並後的序列

2. 設定兩個指針,最初位置分別為兩個已經排序序列的起始位置

3. 比較兩個指針所指向的元素,選擇相對小的元素放入到合並空間,並移動指針到下一位置

4. 重復步驟 3 直到某一指針達到序列尾

5. 將另一序列剩下的所有元素直接復制到合並序列尾

技術分享

四、Dijkstra算法

戴克斯特拉算法(Dijkstra算法)是由荷蘭計算機科學家艾茲赫爾·戴克斯特拉提出。迪科斯徹算法使用了廣度優先搜索解決非負權有向圖的單源最短路徑問題,算法最終得到一個最短路徑樹。該算法常用於路由算法或者作為其他圖算法的一個子模塊。

該算法的輸入包含了一個有權重的有向圖 G,以及 G 中的一個來源頂點 S。我們以 V 表示 G 中所有頂點的集合。每一個圖中的邊,都是兩個頂點所形成的有序元素對。(u,v) 表示從頂點 u 到 v 有路徑相連。我們以 E 表示 G 中所有邊的集合,而邊的權重則由權重函數 w:E→[0,∞] 定義。因此,w(u,v) 就是從頂點 u 到頂點 v 的非負權重(weight)。邊的權重可以想像成兩個頂點之間的距離。任兩點間路徑的權重,就是該路徑上所有邊的權重總和。已知有 V 中有頂點 s 及 t,Dijkstra 算法可以找到 s 到 t 的最低權重路徑 (例如,最短路徑)。這個算法也可以在一個圖中,找到從一個頂點 s 到任何其他頂點的最短路徑。對於不含負權的有向圖,Dijkstra 算法是目前已知的最快的單源最短路徑算法。

算法步驟:

1. 初始時令 S={V0},T={其余頂點},T 中頂點對應的距離值

若存在,d(V0,Vi) 為弧上的權值

若不存在,d(V0,Vi) 為∞

2. 從 T 中選取一個其距離值為最小的頂點 W 且不在 S 中,加入 S

3. 對其余 T 中頂點的距離值進行修改:若加進 W 作中間頂點,從 V0 到 Vi 的距離值縮短,則修改此距離值

重復上述步驟 2、3,直到 S 中包含所有頂點,即 W=Vi 為止

技術分享

五、Bellman-Ford算法

Bellman-Ford算法能在更普遍的情況下(存在負權邊)解決單源點最短路徑問題。對於給定的帶權(有向或無向)圖 G=(V , E),其源點為 s,加權函數 w 是邊集 E 的映射。對圖 G 運行Bellman-Ford算法的結果是一個布爾值,表明圖中是否存在著一個從源點 s 可達的負權回路。若不存在這樣的回路,算法將給出從源點 s 到圖 G 的任意頂點 v 的最短路徑d[v]。Bellman-Ford算法是在帶權圖中計算從單一源點出發到其他節點的最短路徑的算法。盡管算法復雜度大於 Dijkstra 算法,但是它適用於包含了負值邊的圖。

技術分享

六、Prim算法

普裏姆算法(Prim算法),圖論中一種重要的算法,可在加權連通圖裏搜索最小生成樹。意即由此算法搜索到的邊子集所構成的樹中,不但包括了連通圖裏的所有頂點(英語:Vertex (graph theory)),且其所有邊的權值之和亦為最小。Prim算法是用於在帶權無向圖中計算最小生成樹的貪婪算法。換言之,它能夠在圖中抽取出連接所有節點的邊的最小代價子集。

技術分享

七、Kruskal算法

克魯斯卡爾算法(ruskal算法)同樣是計算圖的最小生成樹的算法,跟 Prim 算法的區別在於Kruskal算法不需要圖是連通的。

技術分享

作者:耑新新,發布於 博客園

轉載請註明出處,歡迎郵件交流:[email protected]

圖解常用算法