最小生成树之普里姆算法
2016-02-19 22:58
267 查看
//lowcost数组里的值是adjvex数组里的点指向相应下标的点的权值 //lowcost数组保存相关顶点到邻接点(边)的权值,此权值是生成树里的点到该邻接点的最小权值 /*例如: 0 1 2 3 4 5 6 A B C D E F G adjvex: 0 0 0 0 3 3 0 lowcost:0 7 x 0 15 6 x lowcost[1]=7的意思是:0顶点(A)(adjvex[1])指向B点(相应下标)的权值 lowcost[4]=15的意思是:3顶点(D)(adjvex[4])指向E(相应下标)的权值 */ #include <stdio.h> #include <stdlib.h> #include <string.h> typedef char VertexType; //顶点类型应由用户定义 typedef int EdgeTyep; //边上的权值类型应由用户定义 #define MAXVEX 100 //最大顶点数,应由用户定义 #define INFINITY 65535 //用65535来代表无穷大 #define DEBUG typedef struct Graph{ VertexType vexs[MAXVEX]; //顶点表 EdgeTyep arc[MAXVEX][MAXVEX]; //邻接矩阵,可看作边 int numVertexes, numEdges; //图中当前的顶点数和边数 }Graph; //定位 int Locates(Graph *g, char ch) { int i; for(i = 0; i < g->numVertexes; i++) { if(g->vexs[i] == ch) break; } if(i >= g->numVertexes) return -1; return i; } //建立一个无向网图的邻接矩阵表示 void CreatGraph(Graph *g) { int i, j, w, k; printf("please input numVertexes and numEdges\n"); scanf("%d %d", &(g->numVertexes), &(g->numEdges)); getchar();//下面要输入字符,所以要吃回车 #ifdef DEBUG//调试用 printf("%d %d\n", g->numVertexes, g->numEdges); #endif for(i = 0; i < g->numVertexes; i++) { printf("请输入顶点%d:\n", i); scanf("%c", &(g->vexs[i])); getchar(); /*g->vexs[i] = getchar(); while(g->vexs[i] == '\n')//吃回车 { g->vexs[i] = getchar(); }*/ } #ifdef DEBUG for(i = 0; i < g->numVertexes; i++) { printf("%c ", g->vexs[i]); } printf("\n"); #endif for(i = 0; i < g->numEdges; i++) { for(j = 0; j < g->numEdges; j++) { g->arc[i][j] = INFINITY; //邻接矩阵初始化 } } //getchar();//注意吃回车 for(k = 0; k < g->numEdges; k++) { char p, q; printf("please input i, j, w in Edge(vi, vj)\n"); scanf("%c %c %d", &p, &q, &w); getchar();//吃回车 int m = -1; int n = -1; m = Locates(g, p); n = Locates(g, q); if(n == -1 || m == -1) { printf("There is no vertex !\n"); return ; } g->arc[m] = w; g->arc [m] = g->arc[m] ; //因为是无向图,矩阵对称 } } //打印图 void printGraph(Graph g) { int i, j; printf("The Graph is under this sentence\n"); for(i = 0; i < g.numVertexes; i++) { for(j = 0; j < g.numVertexes; j++) { printf("%5d ", g.arc[i][j]); } printf("\n"); } } //prime算法最小生成树 void MiniSpanTree_Prime(Graph g) { int mins, i, j, k; int adjvex[MAXVEX]; //保存相关顶点下标 int lowcost[MAXVEX]; //保存相关顶点到邻接点(边)的权值,此权值是生成树里的点到该邻接点的最小权值 lowcost[0] = 0; //初始化第一个权值为0,即v0加入生成树 adjvex[0] = 0; //初始化第一个顶点下标为0 for(i = 1; i < g.numVertexes; i++) { //循环除下标为0外的全部顶点 lowcost[i] = g.arc[0][i]; //将v0顶点与之有边的权值存入数组 adjvex[i] = 0; //初始化都为v0下标 } for(i = 1; i < g.numVertexes; i++) { mins = INFINITY; //初始化最小权值为无穷大 j = 1; k = 0; while(j < g.numVertexes) //循环全部顶点 {//如果权值不为0,且权值小于min if(lowcost[j] != 0 && lowcost[j] < mins) { mins = lowcost[j]; //则让mins成为最小权值 k = j; //记录当前最小权值的下标 } j++; } printf("(%d,%d)", adjvex[k], k);//打印当前顶点边中权值最小边//如果要建树就在这里加代码 lowcost[k] = 0; //将当前顶点的权值设置为0,表示此点为顶点且已经加入生成树 for(j = 1; j < g.numVertexes; j++) { if(lowcost[j] != 0 && g.arc[k][j] < lowcost[j])//如果k顶点到j顶点的边的权值小于现在lowcost数组中其他已记录的其他的点到j顶点的最小权值,则更新他 { lowcost[j] = g.arc[k][j]; adjvex[j] = k; } } } printf("\n"); } int main() { Graph g; //邻接矩阵创建图 CreatGraph(&g); //打印网图 printGraph(g); //求最小生成树 MiniSpanTree_Prime(g); return 0; }
相关文章推荐
- C#Light 和 uLua的对比第二弹
- 图论之广度优先遍历
- Unity3D逻辑热更新,第二代舒爽解决方案,L#使用简介
- NSSortDescriptor对象进行数组排序
- Smart L 客户端设计 - 主题布局
- 图论之深度优先遍历
- Centos安装MySQL
- 20160219模拟
- U-Boot中改用DM8168的UART0
- 蓝桥杯 历届试题 翻硬币
- 王阳明的知行合一为什么特别厉害?看蒋介石的例子就知道了
- 王阳明的知行合一为什么特别厉害?看蒋介石的例子就知道了
- Unity3D热更新 下载
- C++之 浅拷贝和深拷贝
- 字典树hihocoder1014
- 独立模式安装sharepoint 2013,配置向导报错解决方案
- Unity3d热更新 加载(二)如何在不用AssetBundle的前提下动态加载预设
- bzoj1087【SCOI2005】互不侵犯King
- Android Studio的使用
- Github 搭建 hexo (二)—— helloworld