最小生成樹其他做法:破圈法
克魯斯卡爾的思路:
1. 從邊出發,找到所有邊,並以邊的權值從小到大進行排序
這裡用到了c中的qsort對結構體陣列進行排序。
qsort需要我們提供乙個cmp函式
int
cmp(
const
void
*a,const
void
*b)qsort
(arr, ga->e,
sizeof
(edge)
, cmp)
;// 引數分別為: 結構體陣列,
// 需要排序的個數,
// 該結構體陣列的大小,
// 排序規則函式
2.一次遍歷,選擇最小的權值邊新增到樹中(若該條邊新增後,樹中存在環路,則不應該新增這條邊)。
我們可以通過乙個尾節點陣列,存放新增到樹中的尾標識,若該尾標識重複出現則說明當前形成了環路
int end_index=0;
int ends[ga->n]
;ends[end_index]
= arr[0]
.en;
printf
("%c到%c\n"
,ga->vexs[arr[0]
.beg]
,ga->vexs[arr[0]
.en]);
//第一條直接新增,並且輸出(第一條必不可能形成迴路)
// 這裡的vexs 存放的是頂點元素
//遍歷所有邊
for(i=
1;ie;i++)}
if(flag==0)
// 邊數為 (頂點數-1) 則不再尋找
if(e_flag == ga->n-1)
}
若選擇新增到樹中的邊數達到(總頂點數-1) 即不再尋找新的邊。
完整**:
#include
#include
#define maxvex 16
typedef
char vextype;
/*頂點的資料型別*/
typedef
int adjtype;
/*鄰接矩陣的資料元素的型別*/
typedef
struct
graphmatrix;
typedef
struct treedata edge;
graphmatrix*
creategraph
(void
)//建立無向帶權圖
else
}/*鄰接矩陣初始化*/
printf
("請輸入邊的個數:");
scanf
("%d"
,&e)
; ga->e = e;
printf
("請輸入與邊相關聯的兩個頂點的序號:\n");
for(k=
0;k)getchar()
;return ga;
}void
printgraph
(graphmatrix *ga)
}int
cmp(
const
void
*a,const
void
*b)void
kruskal
(graphmatrix *ga)}}
// arr 根據arr.length 排序 從小到大!
for(i=
0;ie;i++
)printf
("根據length 排序後:\n");
qsort
(arr, ga->e,
sizeof
(edge)
, cmp)
;for
(i=0
;ie;i++
)// 2. 篩選最小邊 判斷是否是迴路。
int e_flag =0;
// 如果邊數為 (頂點數-1) 則不再尋找
int end_index=0;
int ends[ga->n]
; ends[end_index]
= arr[0]
.en;
printf
("%c到%c\n"
,ga->vexs[arr[0]
.beg]
,ga->vexs[arr[0]
.en]);
e_flag++
;for
(i=1
;ie;i++)}
if(flag==0)
// 邊數為 (頂點數-1) 則不再尋找
if(e_flag == ga->n-1)
}}intmain()
測試用例1:
請輸入頂點的個數(不超過16):6
請順序地輸入各頂點的資訊(序號即可,用乙個字元表示):
012345
請輸入邊的個數:8
請輸入與邊相關聯的兩個頂點的序號:
0 1 1
0 2 5
0 3 2
1 4 7
1 2 3
2 5 6
3 5 8
4 5 4
輸出頂點表為:
0 1 2 3 4
鄰接矩陣為:
0 1 5 2 999 9
1 0 3 999 7 9
5 3 0 999 999
2 999 999 0 999
999 7 999 999 0
999 999 6 8 4
0 -> 1 值為 1
0 -> 2 值為 5
1 -> 2 值為 3
0 -> 3 值為 2
1 -> 4 值為 7
2 -> 5 值為 6
3 -> 5 值為 8
4 -> 5 值為 4
根據length 排序後:
0 -> 1 值為 1
0 -> 3 值為 2
1 -> 2 值為 3
4 -> 5 值為 4
0 -> 2 值為 5
2 -> 5 值為 6
1 -> 4 值為 7
3 -> 5 值為 8
0到1
0到31到2
4到51到4
參考
Kruskal演算法實現最小生成樹
kruskal演算法思想 g v,e 是無向連通網,t u,te 是g的最小生成樹演算法的基本思想是 初始狀態為u v te 即t中的頂點各自構成乙個連通分量,然後按照邊的權值由小到大的順序,依次考察邊e中的各條邊。若被考察邊的兩個頂點屬於兩個不同的連通分量,則將此邊加入到te中,同時把兩個連通分量...
最小生成樹 kruskal(演算法)
最小生成樹 圖中有好多點呀 n個 讓我們找到n 1條邊,來把他們連上吧,但是要讓這n 1條邊的和最小。kruskal演算法 把所有邊由公升序排列,然後從最小的一條邊找起,如果這條邊的兩點不屬於乙個集合 此處運用並查集 那麼就要這條邊,否則,忽略這條邊吧 一直這樣找下去,直到找了n 1條邊為止,此時,...
最小生成樹 Kruskal演算法
1.概覽 kruskal演算法是一種用來尋找最小生成樹的演算法,由joseph kruskal在1956年發表。用來解決同樣問題的還有prim演算法和boruvka演算法等。三種演算法都是貪婪演算法的應用。和boruvka演算法不同的地方是,kruskal演算法在圖中存在相同權值的邊時也有效。2.演...