kruskal算法

克鲁斯卡尔算法
克鲁斯卡尔算法是为了使生成树上边的权值之和达到最小,因此应使生成树中每一条边的权值尽可能小,具体做法:

  1. 将图中所有边按权值递增顺序排序。
  2. 先构造一个只包含n个顶点的子图。
  3. 依次选取权值较小的边,但要求后面选取的边不能与前面选取的边构成回路,若构成回路则放弃该条边,再去选取后面权值较大的边。
  4. 重复步骤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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值