最小生成树——Prim算法(王道版)

参考王道《2023年数据结构考研复习指导》

#include <iostream>

#define MaxVerTexNum 20

typedef char VertexType;							// 顶点的数据类型
typedef int EdgeType;								// 带权图中边上权值的数据类型

// 邻接矩阵存储图
typedef struct {
	VertexType Vex[MaxVerTexNum];					// 顶点表
	EdgeType Edge[MaxVerTexNum][MaxVerTexNum];		// 邻接矩阵,边表(-1代表无穷大)
	int vexnum, arcnum;								// 图的当前顶点数和边数/弧数
} MGraph;

void MiniSpanTree_Prim(MGraph G, int u);
void Visit(const MGraph& G, int u, int v);

int main() {
	MGraph G = {
		{'1', '2', '3', '4', '5', '6'},
		{
			{-1, 6, 1, 5, -1, -1},
			{6, -1, 5, -1, 3, -1},
			{1, 5, -1, 5, 6, 4},
			{5, -1, 5, -1, -1, 2},
			{-1, 3, 6, -1, -1, 6},
			{-1, -1, 4, 2, 6, -1}
		},
		6, 10
	};

	MiniSpanTree_Prim(G, 0);

	system("pause");
	return 0;
}

// 从顶点u出发,构造最小生成树,并输出生成树的每条边
void MiniSpanTree_Prim(MGraph G, int u) {
	struct {
		int adjvex;							// 顶点编号
		int lowcost;						// 从顶点adjvex到当前顶点的权值(为0代表已加入集合U)
	}closedge[MaxVerTexNum];				// 求最小生成树时的辅助数组

	for (int i = 0; i < G.vexnum; ++i) {
		closedge[i].adjvex = u;
		closedge[i].lowcost = G.Edge[u][i];
	}

	closedge[u].lowcost = 0;				// 初始化,U = {u}

	for (int i = 1; i < G.vexnum; ++i) {	// 找n-1条边
		int min = -1;						// closedge数组中的最小权值
		int v;								// 下一个加入集合U的顶点

		for (int j = 0; j < G.vexnum; j++) {	// 找到closedge数组中的最小边
			if (min == -1 && closedge[j].lowcost > 0) {
				min = closedge[j].lowcost;
				v = j;
			}
			if (min != -1 && closedge[j].lowcost > 0 && closedge[j].lowcost < min) {
				min = closedge[j].lowcost;
				v = j;
			}
		}

		closedge[v].lowcost = 0;				// 将顶点v纳入集合U
		int u = closedge[v].adjvex;		
		Visit(G, u, v);

		for (int j = 0; j < G.vexnum; ++j) {	// 在顶点v并入U之后,更新closedge[i]
			if (closedge[j].lowcost != 0 && G.Edge[v][j] > 0) {
				if (closedge[j].lowcost == -1)
				{
					closedge[j].adjvex = v;
					closedge[j].lowcost = G.Edge[v][j];
				}
				else if (closedge[j].lowcost != -1 && G.Edge[v][j] < closedge[j].lowcost) {
					closedge[j].adjvex = v;
					closedge[j].lowcost = G.Edge[v][j];
				}
			}
		}
	}
}

void Visit(const MGraph& G, int u, int v) {
	std::cout << G.Vex[u] << " -> " << G.Vex[v] << " : " << G.Edge[u][v] << std::endl;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈阿土i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值