轉接上一篇,地址:https://blog.csdn.net/q1119823309/article/details/90703135
我的碼雲地址:碼雲地址
開始
統一:假設圖沒有自環邊和平行邊
1. 稠密圖 - 鄰接矩陣
對於稠密圖,使用鄰接矩陣來表示,用一個n*n二維數組(n個節點)來表示是否有邊。
2. 稀疏圖 - 鄰接表
對於稀疏圖,使用鄰接表來表示,用鏈表數組來存儲連接信息
3. 圖的操作
- 使用深度遍歷來求圖的連通分量
- 使用棧進行廣度優先遍歷(尋路算法)
4. 最小生成樹算法
- lazy prim 算法(算法複雜度 O( E log(E))
先定一個起點,記錄起點並找到該點連接的所有未訪問過的邊放入最小堆中,找到最小邊,判斷是否訪問過的點,是就拋棄,不是就記錄該點,並將該點連接的所有未訪問過的邊加入最小堆中。。。直到所有點都記錄完全。 - prim 算法(優化、算法複雜度O( E log(V))
優化 lazy prim 算法,將最小堆改爲最小索引堆。堆中 data 存權值,index作爲連接的點,若訪問點連接的點的邊在堆中爲空或者比堆中的小就替換該點的 data 值。 - kruskal 算法(算法複雜度(O( E log(E))
把所有邊都加入到最小堆中,把最小的邊取出來,通過並查集判斷兩點是否連通,不連通則記錄點和邊,並將加入到並查集中,以此類推。
單源最短路徑算法
鬆弛操作:嘗試能不能從一點出發經由另外的點找到到另一點更短的路徑
- Dijkstra 算法(算法複雜度O( E log(V))
前提:不能有負權邊
從定義的起點開始,把點和邊加入到最小索引堆中,記錄該點,把連接的邊都取出來判斷連接的點是否被記錄,記錄的點丟棄,否則判斷連接的點是爲空則加入堆中,或者值比連接的邊大則改變權值,以此類推。 - Bellman-Ford 算法(算法複雜度(O( E V ))
前提:可以有負權邊但不能有負權環。(可以判斷是否後負權環)
從0開始遍歷 V-1 遍,每一遍都對所有邊進行鬆弛操作,早點更小的路徑並更新。遍歷晚後可再進行對所有邊進行一次鬆弛操作,如果此時有更小的路徑更新則該圖有負權環。
優化: 利用隊列數據結構進行優化(queue-based bellman-ford算法)
擴展
- 對於有向無環圖(DAG)可使用拓撲排序,算法複雜度O( V+E )
- 所有點最短路徑算法,可以執行V次Dijkstra算法或者Bellman-Ford算法,也可以使用Floyed算法,處理無負權環的圖,算法複雜度O(V^3)
- 最長路徑算法不能有正權環,指數級的難度,無權圖的問題是指數級難度的,而對於有權圖不能使用Dijkstra算法。可以使用Bellman-Ford算法(將所有權值取負)
算法思想:
- 分治:歸併排序;快速排序;樹結構
- 貪心:選擇排序;堆;Kruskal;Prim;Dijkstra
- 遞歸回溯:樹的遍歷;圖的遍歷
- 動態規劃:Prim;Dijkstra