生動的普里姆演算法詳解

2021-09-30 16:40:24 字數 1382 閱讀 9787

針對無向圖用來生成最小生成樹的演算法。

起始條件:

讓我們來系統的執行一次:

乙個孤苦伶仃的起始點小明看著周圍的點點們都不和自己在乙個集合裡,於是很想找同伴,但是怎麼找呢?它發現,自己和一些點身上綁著一條線(距離為線的權值),而和另一部分點則沒有連線(距離為inf)(這些全都儲存在陣列a裡,a['連線的點']=權值,a['不連線的點']=inf,也就是無窮大,姑且把a陣列稱為上帝面板。),很明顯,當然是把距離自己最近的點拉進來啦!小明把最近的小華拽到了自己的集合裡(完成了第一步),現在小華和小明有了同樣的苦惱,當然也要擴充同伴啦!不過小明多了小華這麼乙個盟友,所以,和小華相連的點點們也可以被拽進來,於是更新上帝面板,凡是與小華相連的點到小華的距離小於a['此點']的點,都在上帝面板a上更新,用他們到小華的權值覆蓋原值,同時此刻更新陣列b,b['此點']=小華。到這裡就完成了一次普里姆演算法。

那麼,執行普里姆演算法會導致形成環嗎??這是不會的。我們會在設計演算法的時候破壞這個潛在的可能性。

總結來看,就是不斷地找距離點集裡的點權值最小的邊,然後更新邊集,擴充點集,然後不斷的更新上帝面板和陣列b

下面看一下演算法吧。

void prim(graphclass&gr, int v,t a[maxl])

for (int i = 1;i < gr.g->n;i++)//找出n-1個頂點

//執行完上面的迴圈,我們找到了距離v點集中的元素最近的點,k即為那個點,min即為那個值

//可以說,closest陣列裡儲存的就是一條邊在v點集中的點,然後我們把他輸出出來。

cout << "邊(" << closest[k] << ',' << k << ")權為" << min << endl;

//這一步很關鍵,把走過(已經併入v集)的點在a陣列中的值設定為0,這樣上個迴圈就不會遍歷這條記錄。

lowcost[k] = 0;

//下面要重新設定上帝面板a裡的值了,因為我們的v點集迎來了新成員,所以要重新設定非v點集到v點集的最短距離

for(int j=0;jn;j++)

if (a[k][j] != 0 && a[k][j] < lowcost[j])

}}

這個演算法給我的感覺是,自己內心已經明白他的原理,但是從文字上很難描述的清楚,所以我也在盡力的讓大家能夠明白我的想法,但我的建議是,不要一字一句的對應著我的注釋和**走,而是從一兩行給你啟發的**上入手自己往下想應該怎麼做,然後到這裡你可能就自己明白了,若是仍然模糊,則可以繼續看我的解釋和**來想清除。這都是很順其自然的。

普里姆演算法

include include include include using namespace std define max name 5 define max vertex num 20 權的上限值 typedef char vertex max name 頂點名字串 typedef int ad...

普里姆演算法

普里姆演算法的基本思想如下 假設n 是連通網,te是n上最小生成樹中邊的集合。從u 開始,te 開始,重複執行下述操作 在所有的u屬於u,v屬於v u的邊 u,v 的邊中找到權值最小的一條邊,並且併入te,同時u併入u,直到u v 先設乙個輔助陣列closedge max 初始時先把第乙個結點存入c...

普里姆演算法

include include include using namespace std define maxint 32767 define maxnum 100 typedef struct vnode,closedge maxnum typedef struct amgraph intlocat...