数据结构_最小生成树Prim算法(C语言)

时间:2025-04-15 07:30:00
#include<> #include<> #define MaxVex 10 #define INF 65535 typedef char VertexType; // 顶点的数据类型 typedef int EdgeType; // 边的数据类型 typedef struct { VertexType *vertexs; // 一维数组存放顶点数据 EdgeType **edges; // 二维数组存放边的数据 int numVertexs, numEdges;//顶点数、边数 }AMGraph; // 初始化领接矩阵 void InitAMGraph(AMGraph *G) { // 初始化顶点一维数组 G->vertexs = (VertexType *)malloc(MaxVex*sizeof(VertexType)); // 初始化边的二维数组 int i, j; G->edges = (EdgeType **)malloc(MaxVex*sizeof(EdgeType *)); for (i = 0; i < MaxVex; i++) { G->edges[i] = (EdgeType *)malloc(MaxVex*sizeof(EdgeType)); // 初始化每条边都为INF(无穷大) for ( j = 0; j < MaxVex; j++) { if (i == j) { G->edges[i][j] = 0; // 对角线初始位为0 } else { G->edges[i][j] = INF; // 初始化为无穷大 } } } // 初始化顶点和边的数量 G->numVertexs = 0; G->numEdges = 0; printf("已初始化邻接矩阵!\n"); } // 创建领接矩阵 void CreateAMGraph(AMGraph *G) { printf("请输入顶点数和边数:"); scanf("%d %d", &G->numVertexs, &G->numEdges); int i, j, k, weight; // 输入顶点数据 for (i = 0; i < G->numVertexs; i++) { fflush(stdin); printf("请输入第%d个顶点数据:", i + 1); scanf("%c", &G->vertexs[i]); } // 输入边的权值 for (k = 0; k < G->numEdges; k++) { printf("请输入第%d条边的两顶点及其权值:", k + 1); scanf("%d %d %d", &i, &j, &weight); G->edges[i - 1][j - 1] = weight; // 无向图中,边的两个方向权值相同 G->edges[j - 1][i - 1] = weight; } printf("已完成邻接矩阵的创建!\n"); } // 取最小边的相邻顶点下标 int minAdjVex(EdgeType *minEdge, int size) { EdgeType min; int i, j, k = -1; for (i = 0; i < size; i++) { if (minEdge[i] > 0) { min = minEdge[i]; for (j = 0; j < size; j++) { if (minEdge[j] > 0 && min >= minEdge[j]) { min = minEdge[j]; k = j; } } break; } } return k; } void MiniSpanTree_Prim(AMGraph G, int v) { EdgeType *minEdge; minEdge = (EdgeType *)malloc(G.numVertexs * sizeof(EdgeType)); int i, j, k; // 初始化辅助数组,用于表示最小生成树的顶点集合 for (i = 0; i < G.numVertexs; i++) { // 初始化 顶点[v]到各个顶点[i]的权值 minEdge[i] = G.edges[v][i]; } // 设置顶点[v]到顶点[v]的权值为0(代表顶点[v]加入最小生成树的顶点集合) minEdge[v] = 0; // 依次将最小边相邻的顶点加入集合 for (i = 1; i < G.numVertexs; i++) { // 获取最小生成树集合与其他顶点之间最小边的相邻顶点下标 k = minAdjVex(minEdge, G.numVertexs); printf("{ "); for (j = 0; j < G.numVertexs; j++) { if (minEdge[j] == 0) { printf("%c ", G.vertexs[j]); } } printf("}---(%d)---[%c]\n", minEdge[k], G.vertexs[k]); // 设置集合到顶点[k]的权值为0(代表顶点[k]加入最小生成树顶点集合) minEdge[k] = 0; // 更新集合 到 其他各顶点最小边的权值 for ( j = 0; j < G.numVertexs; j++) { // 顶点[k]到顶点[j]的边权值 小于 原来集合到顶点[j]的边权值 if (G.edges[k][j] < minEdge[j]) { minEdge[j] = G.edges[k][j]; } } } } int main() { AMGraph G; InitAMGraph(&G); CreateAMGraph(&G); MiniSpanTree_Prim(G, 0); system("pause"); return 0; }