44 資料結構筆記之四十四弗洛伊德Floyd演算法

2021-08-08 14:33:09 字數 3098 閱讀 9972

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 表示。編...