設g=(v, e)是具有n個頂點的連通網,t=(u, te)是其最小生成樹。初值:u=v,te={} 。
對g中的邊按權值大小從小到大依次選取。
⑴ 選取權值最小的邊(vi,vj),若邊(vi,vj)加入到te後形成迴路,則捨棄該邊(邊(vi,vj) ;否則,將該邊併入到te中,即te=te∪ 。
⑵ 重複⑴ ,直到te中包含有n-1條邊為止。
kruskal演算法實現的關鍵是:當一條邊加入到te的集合後,如何判斷是否構成迴路?
簡單的解決方法是:定義乙個一維陣列vset[n] ,存放圖t中每個頂點所在的連通分量的編號。
◆ 初值:vset[i]=i,表示每個頂點各自組成乙個連通分量,連通分量的編號簡單地使用頂點在圖中的位置(編號)。
◆ 當往t中增加一條邊(vi,vj) 時,先檢查vset[i]和vset[j]值:
☆ 若vset[i]=vset[j]:表明vi和vj處在同乙個連通分量中,加入此邊會形成迴路;
☆ 若vset[i]≠vset[j],則加入此邊不會形成迴路,將此邊加入到生成樹的邊集中。
◆ 加入一條新邊後,將兩個不同的連通分量合併:將乙個連通分量的編號換成另乙個連通分量的編號。
mstedge *kruskal_mst(elgraph *g)
/* 用kruskal演算法構造圖g的最小生成樹 */
mstedge te ;
int j, k, v, s1, s2, vset ;
weighttype w ;
vset=(int *)malloc(g->vexnum*sizeof(int)) ;
for (j=0; jvexnum; j++)
vset[j]=j ; /* 初始化陣列vset[n] */
sort(g->edgelist) ; /* 對錶按權值從小到大排序 */
j=0 ;
k=0 ;
while (kvexnum-1&&j< g->edgenum)
s1=vset[g->edgelist[j].vex1] ;
s2=vset[g->edgelist[j].vex2] ;
/* 若邊的兩個頂點的連通分量編號不同, 邊加入到te中 */
if (s1!=s2)
te[k].vex1=g->edgelist[j].vex1 ;
te[k].vex2=g->edgelist[j].vex2 ;
te[k].weight=g->edgelist[j].weight ;
k++ ;
for (v=0; vvexnum; v++)
if (vset[v]==s2)
vset[v]=s1 ;
j++ ;
free(vset) ;
return(te) ;
} /* 求最小生成樹的kruskal演算法 */
設帶權連通圖有n個頂點,e條邊,則演算法的主要執行是:
◆ vset陣列初始化:時間複雜度是o(n) ;
◆ 邊表按權值排序:若採用堆排序或快速排序,時間複雜度是o(e㏒e);
◆ while迴圈:最大執行頻度是o(n),其中包含修改vset陣列,共執行n-1次,時間複雜度是o(n2);
整個演算法的時間複雜度是o(e㏒e+n2)。
kruskal克魯斯卡爾演算法
給定乙個帶權的無向連通圖,如何選取一棵生成樹,使樹上所有邊上權的總和為最小,這叫最小生成樹.求最小生成樹的演算法 1 克魯斯卡爾演算法 圖的存貯結構採用 邊集陣列 且權值相等的邊在陣列中排列次序可以是任意的.該方法對於邊相對比較多的不是很實用,浪費時間 方法 將圖中邊按其權值由小到大的次序順序選取,...
克魯斯卡爾演算法 Kruskal
克魯斯卡爾 kruskal 演算法是一種按權值的遞增次序選擇合適的邊來構造最小生成樹的方法。假設g v,e 是乙個具有 n 個頂點的帶權連通圖,t u,t e 是g 的最小生成樹,則構造最小生成樹的步驟如下 1 設定 u的初值等於 v 即包含有 g中的全部頂點 te 的初值為空集 即圖 t 中每乙個...
克魯斯卡爾 Kruskal 演算法
1 克魯斯卡爾演算法使用來求加權連通圖的最小生成樹的演算法 2 基本思想 按照權值從小到大的順序選擇n 1條邊,並保證n 1條邊不構成迴路。3 具體做法 先將各路的權值按照從小到大排序,然後建立乙個最終點的陣列。通過最終點的陣列來實現不構成迴路。構建最小生成樹的節點 頂點 資訊。class edat...