44. 資料結構筆記之四十四弗洛伊德floyd演算法
「希望是厄運的忠實的姐妹。
--普希金」
繼續來看下資料結構圖中的乙個演算法,這個演算法來自圖靈獎得主。
floyd演算法又稱為插點法,是一種用於尋找給定的加權圖中多源點之間最短路徑的演算法。該演算法名稱以創始人之一、2023年圖靈獎獲得者、史丹福大學電腦科學系教授羅伯特·弗洛伊德命名。注意這個可不是心理學的那個弗洛伊德。
是解決任意兩點間的最短路徑
的一種演算法
,可以正確處理有向圖
或負權的最短路徑問題。
演算法的時間複雜度
為o(n3),空間複雜度
為o(n2)。
優點:容易理解,可以算出任意兩個節點之間的最短距離,**編寫簡單。
缺點:時間複雜度比較高,不適合計算大量資料。
通過乙個圖的權值矩陣求出它的每兩點間的最短路徑矩陣。
從圖的帶權鄰接矩陣a=[a(i,j)] n×n開始,遞迴地進行n次更新,即由矩陣d(0)=a,按乙個公式,構造出矩陣d(1);又用同樣地公式由d(1)構造出d(2);……;最後又用同樣的公式由d(n-1)構造出矩陣d(n)。矩陣d(n)的i行j列元素便是i號頂點到j號頂點的最短路徑長度,稱d(n)為圖的距離矩陣,同時還可引入乙個後繼節點矩陣path來記錄兩點間的最短路徑。
採用的是(鬆弛技術),對在i和j之間的所有其他點進行一次鬆弛。所以時間複雜度為o(n^3);
其狀態轉移方程如下: map[i,j]:=min
map[i,j]表示i到j的最短距離,k是窮舉i,j的斷點,map[n,n]初值應該為0.當然,如果這條路沒有通的話,還必須特殊處理,比如沒有map[i,k]這條路
floyd演算法的原理是動態規劃
。設di,j,k為從i到j的只以(1..k)集合中的節點為中間節點的最短路徑的長度。
1. 若最短路徑經過點k,則di,j,k = di,k,k − 1 + dk,j,k − 1;
2. 若最短路徑不經過點k,則di,j,k = di,j,k − 1。
因此,di,j,k = min(di,k,k − 1 + dk,j,k −1,di,j,k − 1)。
floyd-warshall演算法的描述如下:
for k ← 1 to n do
fori ← 1 to n do
for j ← 1 to n do
if (di,k + dk,j < di,j) then
di,j ← di,k + dk,j;
其中di,j表示由點i到點j的代價,當di,j為 ∞ 表示兩點之間沒有任何連線。
如下圖1所示
點與點之間的舉例用矩陣來表示。inf表示點之間不連通。
具體步驟如下圖2,3
初始狀態:s是記錄各個頂點間最短路徑的矩陣。
第1步:初始化s。
矩陣s中頂點a[i][j]的距離為頂點i到頂點j的權值;如果i和j不相鄰,則a[i][j]=∞。實際上,就是將圖的原始矩陣複製到s中。
注:a[i][j]表示矩陣s中頂點i(第i個頂點)到頂點j(第j個頂點)的距離。
第2步:以頂點a(第1個頂點)為中介點,若a[i][j]> a[i][0]+a[0][j],則設定a[i][j]=a[i][0]+a[0][j]。
以頂點a[1]6,上一步操作之後,a[1][6]=∞;而將a作為中介點時,(b,a)=12,(a,g)=14,因此b和g之間的距離可以更新為26。
同理,依次將頂點b,c,d,e,f,g作為中介點,並更新a[i][j]的大小。
原理什麼的都抽象難懂,那麼就來看下**吧!**其實很少的。
輸入兩個引數賦值給n和m.
m值表示輸入m個值的數量。
n表示輸入矩陣的大小。
將任何兩個點間的最大距離設定成無限大。
輸入m數值,3個值,前兩個表示座標,後乙個表示值。
(如 1 0 12 表示a[1][0]=12,表示第1個點到第0個點的權值是12)
然後將矩陣 a和矩陣的對角線清零。
其中矩陣a是初始化的圖,所有直接相連的頂點才有權值。
矩陣d是不斷更新的圖,會計算當前最新的頂點與頂點之間的最小權值,預設是所有都是無限大。
然後迴圈判斷a[i][k]+a[k][j]最後如下圖所示(是**法中的輸入,頂點0 ,1,2,3,4,5,6分別表示頂點a,b,c,d,e,f,g)
#include
#include
#define
max1000000000;
inta[1000][1000],d[1000][1000];
intmain()
for(i=0;i
scanf(
"%d%d%d"
,&x,&y,&z);
a[x][y]=z;
a[y][x]=z; }
for(i=0;i
for(j=0;j
d[i][j]=
max;
for(i=0;i
d[i][i]=0;
a[i][i]=0; }
for(k=0;k
for(i=0;i
for(j=0;j if
(a[i][k]+a[k][j]
d[i][j]=a[i][k]+a[k][j]; if
(a[i][j] > d[i][j] )
a[i][j]= d[i][j]; }
} printf(
"inputthe node a & node b\n");
scanf(
"%d%d"
,&n,&m);
printf(
"%d"
,d[n][m]);
return0;
}
十四 資料結構之鍊錶
include include 資料型別 typedef int elemtype 節點儲存結構,頭結點用來儲存長度 typedef struct node node typedef node ptrtonode 節點指標 typedef ptrtonode position 鍊錶 typedef ...
C 資料結構之佇列(十四)
佇列主要的操作 q.empty 如果隊列為空返回true,否則返回false q.size 返回佇列中元素的個數 q.pop 刪除佇列首元素但不返回其值 q.front 返回隊首元素的值,但不刪除該元素 q.push 在隊尾壓入新元素 q.back 返回佇列尾元素的值,但不刪除該元素如果要使用標準庫...
資料結構之哈弗曼樹與哈弗曼編碼
一.哈弗曼樹和哈弗曼編碼先知 哈弗曼樹是二叉樹中一種特殊的樹,也被稱為最優二叉樹。其通過某種規則 權值 來構造出一哈夫曼二叉樹,在這個二叉樹中,只有葉子節點才是有效的資料節點,其他的非葉子節點是為了構造出哈夫曼而引入的!哈夫曼編碼是通過哈夫曼樹進行的一種編碼,一般情況下,以字元 0 與 1 表示。編...