數(shù)據(jù)結(jié)構(gòu)—弗洛伊德算法

在數(shù)據(jù)結(jié)構(gòu)的學(xué)習(xí)當(dāng)中,圖的處理是必不可少的一項(xiàng)佛纫,對圖進(jìn)行處理時缝彬,最短路徑的求取具有較強(qiáng)的使用性和可行性萌焰,在此,我簡單地對求取最短路徑的算法之一——弗洛伊德算法做出簡單的講解谷浅。

弗洛伊德算法在實(shí)現(xiàn)的時候一個重要的特點(diǎn)就是用循環(huán)的嵌套來進(jìn)行逐個的判斷和更新扒俯。此算法區(qū)分于迪杰斯特拉算法的很大的優(yōu)點(diǎn)就是弗洛伊德算法可以在實(shí)現(xiàn)過后實(shí)現(xiàn)了圖中每一個結(jié)點(diǎn)的對其余各個結(jié)點(diǎn)的最短路徑,而后者只是針對一個目標(biāo)結(jié)點(diǎn)計算出該結(jié)點(diǎn)到其他結(jié)點(diǎn)的最短路徑一疯。但是撼玄,由于這次只是做弗洛伊德算法的講解,對于迪杰斯特拉算法便不予贅述墩邀。

如果要求任意兩個結(jié)點(diǎn)之間的最短路徑掌猛,我們可能已經(jīng)有了簡單的想法,在兩個結(jié)點(diǎn)之間存在直接的路徑時眉睹,比較這個路徑和經(jīng)過一次結(jié)點(diǎn)的中轉(zhuǎn)荔茬,甚至二次只盹、三次、以及多次的中轉(zhuǎn)之后的權(quán)值之和比較兔院,最短的權(quán)值之和就可以確定該路徑為最短路徑;若兩者沒有直接路徑站削,則需考慮在經(jīng)過結(jié)點(diǎn)的中轉(zhuǎn)以后坊萝,無論經(jīng)過了幾次中轉(zhuǎn)結(jié)點(diǎn),只要選出權(quán)值最短的路徑许起,該路徑就是最短路徑十偶。

這便是最短路徑的求取方法。

這個過程看似實(shí)現(xiàn)較難园细,但加上了一些輔助變量后惦积,便可以順利實(shí)現(xiàn)。

但是要加入哪些輔助變量呢猛频?首先需要考慮到的是path數(shù)組存放計算出的最短路徑的結(jié)果狮崩。行標(biāo)表示起點(diǎn)結(jié)點(diǎn),列標(biāo)表示終點(diǎn)結(jié)點(diǎn)鹿寻,則該位置存放的數(shù)據(jù)則是終點(diǎn)結(jié)點(diǎn)的前一個結(jié)點(diǎn)睦柴。

例如:從a到達(dá)c的最短路徑為:a—》b—》c;若a的下標(biāo)是1毡熏;c的下標(biāo)是4坦敌;b的下標(biāo)是2;則path[1][4]=2;若從c到e的最短路徑是c—》d—》a—》e痢法;c狱窘,d,a财搁,e的下標(biāo)分別為3,4,1,5蘸炸;

則path[3][5]=1;在查找最短路徑時的順序則是path[3][5]=1,path[3][1]=4;path[3][4]=3妇拯;路徑順序就為:下標(biāo)5《--1《--4《--3幻馁。

另外,需要加入輔助數(shù)組D越锈,該數(shù)組用于記錄兩結(jié)點(diǎn)直接的最短路徑長度如D[0][3]=3仗嗦;表示從0到3的最短路徑長度為3;

現(xiàn)在甘凭,讓我們回到上述自己設(shè)想的問題稀拐,如何比較兩個結(jié)點(diǎn)之間的路徑長度和呢?

在弗洛伊德算法中丹弱,采用的方法是權(quán)值的更新德撬,以下是弗洛伊德的具體算法铲咨,以便于講解


下面開始對代碼展開講解:

個人認(rèn)為,算法的實(shí)現(xiàn)可以分為兩部分蜓洪,其中每一部分可以用以上的兩個for循環(huán)來劃分纤勒,第一個for循環(huán)如下,進(jìn)行的是權(quán)值和路徑的初始化

D[i][j]=G.arc[i][j]; ? ? ? ? ?//將下標(biāo)為i的結(jié)點(diǎn)與相關(guān)的結(jié)點(diǎn)權(quán)值初始化隆檀,如果有直接路徑摇天,則長度是已知權(quán)值,否則的初始化結(jié)果是無窮

if (D[i][j]<Maxint)

p[i][j]=i; ? ? ? ? ? ? ? ? ? ? ? //已初始化后恐仑,有直接路徑的話終點(diǎn)結(jié)點(diǎn)的前一個結(jié)點(diǎn)便是起點(diǎn)結(jié)點(diǎn)

else

p[i][j]=0; ? ? ? ? ? ? ? ? ? ? ?//沒有直接路徑泉坐,進(jìn)行特殊標(biāo)記。

進(jìn)行了初始化之后裳仆,數(shù)組D內(nèi)的元素應(yīng)該與圖D的權(quán)值數(shù)組G.arc相等腕让,并且數(shù)組path內(nèi)的數(shù)據(jù)也根據(jù)圖中結(jié)點(diǎn)間的關(guān)系獲得了初值。

第二部分體現(xiàn)為針對兩個目標(biāo)結(jié)點(diǎn)加入圖中的每一個結(jié)點(diǎn)作為中轉(zhuǎn)結(jié)點(diǎn)進(jìn)行路徑長度的判斷歧斟,根據(jù)判斷結(jié)果更新兩個數(shù)組內(nèi)容纯丸,這個算法很容易使人聯(lián)想到密碼破解時使用的窮舉法。

代碼如下:

for (i=0;i<G.vexnum;i++)

for(j=0;j<G.vexnum;j++) ? ? ?//起始結(jié)點(diǎn)

for(k=0;k<G.vexnum;k++) ? ?//終點(diǎn)結(jié)點(diǎn)

if (D[j][k]>D[j][i]+D[i][k]) ? ? //j构捡,k是需要更新的兩個結(jié)點(diǎn)液南,現(xiàn)在欲在這兩個結(jié)點(diǎn)中加入下標(biāo)為i的結(jié)點(diǎn),并判斷加入新的結(jié)點(diǎn)以后的路徑長度勾徽。

{

D[j][k]=D[j][i]+D[i][k];

p[j][k]=p[k][i]; ? ? ? ? ? ? ? ? ? //可以更新滑凉,則進(jìn)行數(shù)據(jù)更新。

}

到此喘帚,循環(huán)結(jié)束畅姊,最短路徑的查找也完成。

需要說明的是吹由,每一次數(shù)據(jù)的更新若未,path數(shù)組都保存有前一個結(jié)點(diǎn)的信息,如圖:


首先path[0][1]=0;D[0][1]=6;之后倾鲫,有初始化后的結(jié)果:path[0][2]=0,D[0][2]=1,2和1之間沒有路徑故D[2][1]=Maxint,path[0][1],D[0][1]無需更新粗合,之后,判斷0和3,D[0][3]=Maxint是初始化的結(jié)果乌昔,更新加入2之后成了path[0][3]=2;D[0][3]=3;path[2][3]=0,D[2][3]=2隙疚,path[3][1],D[3][1]=1加入任意結(jié)點(diǎn)之后無需更新,故保持磕道;再進(jìn)行path[0][1],D[0][1]的判斷時供屉,嘗試加入結(jié)點(diǎn)2,不成功,再嘗試加入點(diǎn)3時伶丐,由于D[0][3]已經(jīng)更新為3悼做,所以滿足更新條件,D[0][1]=4,path[0][1]=3完成了從0到1中間大于1個中轉(zhuǎn)結(jié)點(diǎn)的實(shí)現(xiàn)哗魂。

總結(jié)在于肛走,第二部分使用三個for語句的嵌套起到了重要的作用,數(shù)據(jù)的更新和信息的保存也需要準(zhǔn)確理解录别。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羹与,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子庶灿,更是在濱河造成了極大的恐慌,老刑警劉巖吃衅,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件往踢,死亡現(xiàn)場離奇詭異,居然都是意外死亡徘层,警方通過查閱死者的電腦和手機(jī)峻呕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趣效,“玉大人瘦癌,你說我怎么就攤上這事□尉矗” “怎么了讯私?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長西傀。 經(jīng)常有香客問我斤寇,道長,這世上最難降的妖魔是什么拥褂? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任娘锁,我火速辦了婚禮,結(jié)果婚禮上饺鹃,老公的妹妹穿的比我還像新娘莫秆。我一直安慰自己,他們只是感情好悔详,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布镊屎。 她就那樣靜靜地躺著,像睡著了一般伟端。 火紅的嫁衣襯著肌膚如雪杯道。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機(jī)與錄音党巾,去河邊找鬼萎庭。 笑死,一個胖子當(dāng)著我的面吹牛齿拂,可吹牛的內(nèi)容都是我干的驳规。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼署海,長吁一口氣:“原來是場噩夢啊……” “哼吗购!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起砸狞,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤捻勉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后刀森,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體踱启,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年研底,在試婚紗的時候發(fā)現(xiàn)自己被綠了埠偿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡榜晦,死狀恐怖冠蒋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乾胶,我是刑警寧澤抖剿,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站识窿,受9級特大地震影響牙躺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腕扶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一孽拷、第九天 我趴在偏房一處隱蔽的房頂上張望裁奇。 院中可真熱鬧禁熏,春花似錦弦牡、人聲如沸茅诱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽淤井。三九已至滚局,卻和暖如春史简,著一層夾襖步出監(jiān)牢的瞬間乃秀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留跺讯,地道東北人枢贿。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像刀脏,于是被迫代替她去往敵國和親局荚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 圖的概念 圖是一種非線性的數(shù)據(jù)結(jié)構(gòu),一個圖中有兩類東西愈污,一種是結(jié)點(diǎn)耀态,一種是邊.我們用V這個集合來表示節(jié)點(diǎn)(vert...
    fredal閱讀 2,326評論 2 14
  • 維基百科的說法: A搜索算法,俗稱A星算法*暂雹。這是一種在圖形平面上首装,有多個節(jié)點(diǎn)的路徑,求出最低通過成本的算法杭跪。常用...
    wangzun閱讀 1,408評論 0 4
  • 貪心算法 貪心算法總是作出在當(dāng)前看來最好的選擇簿盅。也就是說貪心算法并不從整體最優(yōu)考慮,它所作出的選擇只是在某種意義上...
    fredal閱讀 9,231評論 3 52
  • B樹的定義 一棵m階的B樹滿足下列條件: 樹中每個結(jié)點(diǎn)至多有m個孩子揍魂。 除根結(jié)點(diǎn)和葉子結(jié)點(diǎn)外,其它每個結(jié)點(diǎn)至少有m...
    文檔隨手記閱讀 13,219評論 0 25
  • 課程介紹 先修課:概率統(tǒng)計棚瘟,程序設(shè)計實(shí)習(xí)现斋,集合論與圖論 后續(xù)課:算法分析與設(shè)計,編譯原理偎蘸,操作系統(tǒng)庄蹋,數(shù)據(jù)庫概論,人...
    ShellyWhen閱讀 2,283評論 0 3