Prim最小生成树

来源:互联网 发布:java飞机大战子弹 编辑:程序博客网 时间:2024/06/05 04:41

1. 静态的示意

  由N个顶点的无向连通图生成最小生成树的各条边放在容量为N - 1的数组中。

#include <stdio.h>#include <stdlib.h>#define N 6//N个顶点struct Edge {int i; int j; int w;};//i: 起点下标 j: 终点下标 w: 权//int (*adjmatrix)[N]: 邻接矩阵行地址//Edge edge[N - 1]: 输出边表void PrimMST(const int (*adjmatrix)[N], Edge edge[N - 1]){int edge_count = 0;//当前输出边表元素个数int vex[N] = {};//存放已加入的顶点下标int vex_count = 0;//已加入的顶点个数bool joint[N] = {};//i号点是否加入顶点表,默认未加入int shortest = INT_MAX;//最短边长Edge first_edge;for (int i = 0; i < N; i++)//寻找初始最短边{for (int j = i; j < N; j++)//因为是无向图只考虑上三角{if (adjmatrix[i][j] < shortest){first_edge.i = i;first_edge.j = j;first_edge.w = adjmatrix[i][j];shortest = adjmatrix[i][j];}}}edge[edge_count++] = first_edge;//边表首元素vex[vex_count++] = first_edge.i;//顶点表首元素vex[vex_count++] = first_edge.j;//此时顶点表2个元素joint[first_edge.i] = true;joint[first_edge.j] = true;while (edge_count < N - 1){//补集中找最短边shortest = INT_MAX;//save_i, save_j用于存放找到的最近点形成的边所构成的线段端点下标int save_i;int save_j;for (int i = 0; i < vex_count; i++)//点表中{for (int j = 0; j < N; j++){if (!joint[j] && adjmatrix[vex[i]][j] < shortest)//没有加入顶点表且权最小{shortest = adjmatrix[vex[i]][j];save_i = vex[i];save_j = j;}}}joint[save_j] = true;//标记save_jvex[vex_count++] = save_j;//顶点表中加入save_j点号edge[edge_count].i = save_i;edge[edge_count].j = save_j;edge[edge_count].w = adjmatrix[save_i][save_j];edge_count++;}}int main(){int adjmatrix[N][N] = {INT_MAX, 6, 1, 5, INT_MAX, INT_MAX,6, INT_MAX, 5, INT_MAX, 3, INT_MAX,1, 5, INT_MAX, 5, 6, 4,5, INT_MAX, 5, INT_MAX, INT_MAX, 2,INT_MAX, 3, 6, INT_MAX, INT_MAX, 6,INT_MAX, INT_MAX, 4, 2, 6, INT_MAX};//N * N邻接矩阵Edge e[N - 1];//存放输出结果的边表PrimMST(adjmatrix, e);//测试静态情况下的函数for (int i = 0; i < N - 1; i++){printf("p%d = %d, p%d = %d, w%d%d = %d\n", i + 1, e[i].i + 1, i + 2, e[i].j + 1, i + 1, i + 2, e[i].w);}return 0;}

2. 实际使用会用到给定长度的邻接矩阵(动态分配的)
#include <stdio.h>#include <stdlib.h>#define N 6//N个顶点struct Edge {int i; int j; int w;};//i: 起点下标 j: 终点下标 w: 权//对动态分配的邻接矩阵生成最小生成树//int ** adjmatrix: 动态分配的邻接矩阵//int n: 顶点个数//Edge * edge: 存放n - 1条边的数组void PrimMSTDynamic(int ** adjmatrix, int n, Edge * edge){int edge_count = 0;//当前输出边表元素个数int * vex = (int *)malloc(n * sizeof(int));//存放已加入的顶点下标int vex_count = 0;//已加入的顶点个数bool * joint = (bool *)malloc(n * sizeof(bool));//i号点是否加入顶点表,默认未加入for (int i = 0; i < n; i++)joint[i] = false;int shortest = INT_MAX;//最短边长Edge first_edge;for (int i = 0; i < n; i++)//寻找初始最短边{for (int j = i; j < n; j++)//因为是无向图只考虑上三角{if (adjmatrix[i][j] < shortest){first_edge.i = i;first_edge.j = j;first_edge.w = adjmatrix[i][j];shortest = adjmatrix[i][j];}}}edge[edge_count++] = first_edge;//边表首元素vex[vex_count++] = first_edge.i;//顶点表首元素vex[vex_count++] = first_edge.j;//此时顶点表2个元素joint[first_edge.i] = true;joint[first_edge.j] = true;while (edge_count < n - 1){//补集中找最短边shortest = INT_MAX;//save_i, save_j用于存放找到的最近点形成的边所构成的线段端点下标int save_i;int save_j;for (int i = 0; i < vex_count; i++)//点表中{for (int j = 0; j < n; j++){if (!joint[j] && adjmatrix[vex[i]][j] < shortest)//没有加入顶点表且权最小{shortest = adjmatrix[vex[i]][j];save_i = vex[i];save_j = j;}}}joint[save_j] = true;//标记save_jvex[vex_count++] = save_j;//顶点表中加入save_j点号edge[edge_count].i = save_i;edge[edge_count].j = save_j;edge[edge_count].w = adjmatrix[save_i][save_j];edge_count++;}free(vex);free(joint);}int main(){int adjmatrix[N][N] = {INT_MAX, 6, 1, 5, INT_MAX, INT_MAX,6, INT_MAX, 5, INT_MAX, 3, INT_MAX,1, 5, INT_MAX, 5, 6, 4,5, INT_MAX, 5, INT_MAX, INT_MAX, 2,INT_MAX, 3, 6, INT_MAX, INT_MAX, 6,INT_MAX, INT_MAX, 4, 2, 6, INT_MAX};//N * N邻接矩阵//开辟int n = 6;int ** adjmatrix_dynamic = (int **)malloc(n * sizeof(int *));for (int i = 0; i < n; i++){adjmatrix_dynamic[i] = (int *)malloc(n * sizeof(int));}for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){adjmatrix_dynamic[i][j] = adjmatrix[i][j];}}Edge * e_dynamic = (Edge *)malloc((n - 1) * sizeof(Edge));PrimMSTDynamic(adjmatrix_dynamic, n, e_dynamic);//测试动态情况下的函数for (int i = 0; i < n - 1; i++){printf("p%d = %d, p%d = %d, w%d%d = %d\n", i + 1, e_dynamic[i].i + 1, i + 2, e_dynamic[i].j + 1, i + 1, i + 2, e_dynamic[i].w);}//回收for (int i = 0; i < n; i++){free(adjmatrix_dynamic[i]);}free(adjmatrix_dynamic);free(e_dynamic);return 0;}



0 0