克鲁斯卡尔算法
克鲁斯卡尔算法是为了使生成树上边的权值之和达到最小,因此应使生成树中每一条边的权值尽可能小,具体做法:
- 将图中所有边按权值递增顺序排序。
- 先构造一个只包含n个顶点的子图。
- 依次选取权值较小的边,但要求后面选取的边不能与前面选取的边构成回路,若构成回路则放弃该条边,再去选取后面权值较大的边。
- 重复步骤3,在n顶点的图中选购n-1条边即可。
代码实现
#include<iostream>
using namespace std;
#define max 32767;
//用邻接矩阵
typedef struct {
char vexs[100]; //顶点
int arcs[100][100]; //定义邻接矩阵
int vexnum, arcnum; //定义具体顶点数和边数
}AMGraph;
//定义边的数组
struct
{
char head;
char tail;
int lowcost; //权值
}Edge[99*50/2]; //边的数量 n*(n-1)/2
int Vexset[100]; //定义一个辅助数组
//确定位置函数
int LocateVex(AMGraph G, char v) {
for (int i = 0; i < G.vexnum; i++) {
if (G.vexs[i] == v) {
return i;
}
}
return -1;
}
//创建无向图
void CreateUND(AMGraph &G) {
int i, j, k;
cout << "please input the num of vexs and arcs and seperate with space key:" << endl;
cin >> G.vexnum >> G.arcnum;
cout << endl;
cout << "please input the name of vex:" << endl;
for (i = 0; i < G.vexnum; i++) {
cout << "the " << (i + 1) << " name of vexs" << endl;
cin >> G.vexs[i];
}
for (i = 0; i < G.vexnum; i++) {
for (j = 0; j < G.vexnum; j++) {
G.arcs[i][j] = max;
}
}
cout << "please input the lowcost of arcs as a b 7:" << endl;
for (k = 0; k < G.arcnum; k++) {
char v1, v2;
int weight;
cout << "please input " << (k + 1) << " two arc end name and weight " << endl;
cin >> v1 >> v2 >> weight;
i = LocateVex(G, v1);
j = LocateVex(G, v2);
G.arcs[i][j] = weight;
G.arcs[j][i] = G.arcs[i][j];
Edge[k].lowcost = weight;
Edge[k].head = v1;
Edge[k].tail = v2;
}
}
//对边进行排序【冒泡排序】【从小到大】
void sort(AMGraph G) {
int m = G.arcnum - 2;
int flag = 1;
while (m > 0 && flag == 1) {
flag = 0;
for (int i = 0; i <= m; i++) {
if (Edge[i].lowcost > Edge[i + 1].lowcost) {
flag = 1;
char headtemp;
headtemp = Edge[i].head;
Edge[i].head = Edge[i + 1].head;
Edge[i + 1].head = headtemp;
char tailtemp;
tailtemp = Edge[i].tail;
Edge[i].tail = Edge[i + 1].tail;
Edge[i + 1].tail = tailtemp;
int lowcosttemp;
lowcosttemp = Edge[i].lowcost;
Edge[i].lowcost = Edge[i + 1].lowcost;
Edge[i + 1].lowcost = lowcosttemp;
}
}
m--;
}
}
//Kruskal算法
void kruskal(AMGraph G)
{
int i, j, v1, v2, vs1, vs2;
sort(G);
for (i = 0; i < G.vexnum; i++)
{
Vexset[i] = i;
5}
for (i = 0; i < G.arcnum; i++)
{
v1 = LocateVex(G, Edge[i].head);
v2 = LocateVex(G, Edge[i].tail);
vs1 = Vexset[v1];
vs2 = Vexset[v2];
if (vs1 != vs2)
{
cout << Edge[i].head << "--->" << Edge[i].tail << endl;
for (j = 0; j < G.vexnum; j++)
{
if (Vexset[j] == vs2)
{
Vexset[j] = vs1;
}
}
}
}
}
void main() {
AMGraph G;
CreateUND(G);
cout << endl;
kruskal(G);
}