第六章算法6.9-克鲁斯卡尔算法

第六章算法6.9-克鲁斯卡尔算法,第1张

第六章算法6.9-克鲁斯卡尔算法 算法6.9-克鲁斯卡尔算法

代码实现
#pragma once
#include 
#include 

using namespace std;

//图的邻接矩阵存储
//表示极大值
#define MaxInt 32767
//最大顶点数
#define MVNum 100
//顶点类型
typedef char VerTexType;
//边上的权值类型
typedef int ArcType;

typedef struct
{
	//顶点表
	VerTexType vexs[MVNum];
	//邻接矩阵
	ArcType arcs[MVNum][MVNum];
	//图中当前顶点数和边数
	int vexnum, arcnum;
}AMGraph;

//辅助数组Edges的定义
struct Edges{
	VerTexType Head;//边的始点					
	VerTexType Tail;//边的终点				
	ArcType lowcost;//边上的权值					
}Edge[(MVNum * (MVNum - 1)) / 2];

//辅助数组Vexset的定义
int Vexset[MVNum];

//自己定义的排序规则 
int cmp(Edges &s1, Edges& s2)
{
	return s1.lowcost < s2.lowcost;

}


//图G中查找顶点u,返回下标;不存在返回-1
int LocateVex(AMGraph G, VerTexType v)
{
	int i;
	for (i = 0; i < G.vexnum; i++)
	{
		if (v == G.vexs[i])
		{
			return i;
		}

	}
}

void CreateUDN(AMGraph& G)
{
	VerTexType v1, v2;
	ArcType w;
	int row;
	int col;
	//输入总顶点数,总边数
	cout << "请输总顶点数:";
	cin >> G.vexnum;
	cout << "请输总边数:";
	cin >> G.arcnum;
	//依次输入点的信息
	for (int i = 0; i < G.vexnum; i++)
	{
		cout << "输入顶点:";
		cin >> G.vexs[i];
	}
	//初始化邻接矩阵,边的权值置为最大值MaxInt
	for (int m = 0; m < G.vexnum; m++)
	{
		for (int n = 0; n < G.vexnum; n++)
		{
			G.arcs[m][n] = MaxInt;
		}
	}
	//构造邻接矩阵
	for (int k = 0; k < G.arcnum; k++)
	{
		cout << "输入边依附的顶点以及权值:";
		cin >> v1 >> v2 >> w;
		row = LocateVex(G, v1);
		col = LocateVex(G, v2);
		G.arcs[row][col] = w;
		G.arcs[col][row] = G.arcs[row][col];
		Edge[k].lowcost = w;
		Edge[k].Head = v1;
		Edge[k].Tail = v2;
	}
}



//输出无向网的邻接矩阵
void ShowGraph(AMGraph G)
{
	cout << "无向网的邻接矩阵为:" << endl;
	for (int i = 0; i < G.vexnum; i++)
	{
		for (int j = 0; j < G.vexnum; j++)
		{
			if (G.arcs[i][j] == MaxInt)
			{
				cout << "∞" << " ";
			}
			else
			{
				cout << G.arcs[i][j] << " ";
			}

		}
		cout << endl;
	}

}


//无向网G以邻接矩阵形式存储,构造G的最小生成树T,输出T的各条边
void MiniSpanTree_Kruskal(AMGraph G)
{
	//将数组Edge中的元素按权值从小到大排序 
	sort(Edge, Edge + G.arcnum, cmp);
	//辅助数组,表示各顶点自成一个连通分量
	for (int i = 0; i < G.vexnum; i++)
	{
		Vexset[i] = i;
	}

	//依次查看数组Edge中的边
	for (int j = 0; j < G.arcnum; j++)
	{
		//v1为边的始点Head的下标
		int v1 = LocateVex(G, Edge[j].Head);
		//v2为边的终点Tail的下标 
		int v2 = LocateVex(G, Edge[j].Tail);
		//v2为边的终点Tail的下标 
		int vs1 = Vexset[v1];
		//获取边Edge[i]的终点所在的连通分量vs2 
		int vs2 = Vexset[v2];
		//边的两个顶点分属不同的连通分量 
		if (vs1 != vs2)
		{
			//边的两个顶点分属不同的连通分量 
			cout << Edge[j].Head << "--->" << Edge[j].Tail << endl;
			//合并vs1和vs2两个分量,即两个集合统一编号 
			for (int k = 0; k < G.vexnum; k++)
			{
				//集合编号为vs2的都改为vs1 
				if (Vexset[k] == vs2)
				{
					Vexset[k] = vs1;
				}
			}
		}
	}

}



int main() {

	AMGraph G;
	//创建无向网的邻接矩阵
	CreateUDN(G);
	//输出无向网的邻接矩阵
	ShowGraph(G);

	
	cout << "************算法6.9 克鲁斯卡尔算法**************" << endl;
	MiniSpanTree_Kruskal(G);

	system("pause");
	return 0;
}

运行结果

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5636060.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存