参考王道《2023年数据结构考研复习指导》
#include#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; }



