邻接矩阵实现克鲁斯卡尔算法
2016-08-03 01:10
330 查看
//主要源代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define INF 999999 #define MAX_NAME 3 #define VERTEX_MAX_NUM 100 typedef char VertexType[MAX_NAME]; typedef int VRType; typedef struct { //建立邻接矩阵 int weight; }adjMatrix[VERTEX_MAX_NUM][VERTEX_MAX_NUM]; struct MGraph{ VertexType vex[VERTEX_MAX_NUM];//建立顶点向量 adjMatrix arcs; //图中的邻接矩阵 int vrtnum,arcnum;//顶点,弧的个数 }; typedef struct Sort{ int x,y,w; }weightValue[VERTEX_MAX_NUM*VERTEX_MAX_NUM]; typedef struct VRTFather{ int fa; }Father[VERTEX_MAX_NUM]; int LocateVex(MGraph G,VertexType u){ int i; for( i=0;i<G.vrtnum;i++) if(strcmp(u,G.vex[i])==0) return i; return -1; } void creatMGraph(MGraph &G){ int i,j,w; VertexType va,vb; printf("请输入无向图G的顶点数、边数:"); scanf("%d %d",&G.vrtnum,&G.arcnum); printf("请输入%d个顶点的值:\n",G.vrtnum); for(i=0;i<G.vrtnum;i++) //构造顶点向量,(其实就是将顶点的名字换成数字) scanf("%s",G.vex[i]); for(i=0;i<G.vrtnum;i++) //初始化邻接矩阵,都赋为无穷 for(j=0;j<G.vrtnum;j++) G.arcs[i][j].weight=INF; printf("请输入%d条边的顶点1 顶点2 权值(以空格为间隔):\n",G.vrtnum); for(int k=0;k<G.arcnum;k++){ scanf("%s%s%d%*c",va,vb,&w); i=LocateVex(G,va); j=LocateVex(G,vb); G.arcs[i][j].weight=G.arcs[j][i].weight=w; } } void DisplayArc(MGraph g){ printf("建立的邻接矩阵如下:\n "); for(int i=0;i<g.vrtnum;i++) printf("%7s",g.vex[i]); printf("\n"); for(int i=0;i<g.vrtnum;i++){ printf("%s",g.vex[i]); for(int j=0;j<g.vrtnum;j++){ if(g.arcs[i][j].weight==INF) printf(" ∞"); else printf("%7d",g.arcs[i][j].weight); } printf("\n"); } } int findFather(int x,Father &father) { int root;//找x顶点的父亲 while(x!=father[x].fa) x=father[x].fa; root=x;//用temp存储x的最深根节点。即x的父亲结点 return root; } void MiniSpanTree_KRUSKAL(MGraph G){ int min=INF,i,j,vx,vy; weightValue value,temp; Father father; for(i=0;i<G.vrtnum;i++)//初始化所有顶点的父亲为他自己 father[i].fa=i; int k=0; //将所有的边(包括边两端顶点信息),赋值到value结构体数组中 for(i=0;i<G.vrtnum;i++) for(j=0;j<G.vrtnum;j++,k++){ value[k].w=G.arcs[i][j].weight; value[k].x=i;value[k].y=j; } //对value数组中所有的边进行从大到小排序 for(i=0; i<G.vrtnum*G.vrtnum-1; i++) for(j=0; j<G.vrtnum*G.vrtnum-1-i; j++){ if(value[j].w>value[j+1].w){ temp[0]=value[j+1]; value[j+1]=value[j]; value[j]=temp[0]; } } printf("克鲁斯卡尔算法的最小生成树为:\n"); int allcost=0; for(i=0;i<2*G.arcnum-1;i+=2){ //从value数组中每隔两个点进行取边的值,因为无向图中每个顶点的值有两个 int a,b; a=value[i].x; b=value[i].y; if(findFather(a,father)!=findFather(b,father)){ //当前边和其他边不构成环,就输出这条边 printf("(%s-%s) %d\n",G.vex[a],G.vex[b],G.arcs[a][b].weight); //将此边的右顶点的父亲赋值为左顶点的父亲 father[father[b].fa].fa=findFather(a,father); allcost+=G.arcs[a][b].weight;//每输出一次,累加此边的权值 } } printf("最小二叉树的最小权值为:%d\n",allcost); } int main(){ MGraph g; creatMGraph(g); DisplayArc(g); MiniSpanTree_KRUSKAL(g); return 0; } /* 测试样例: v0 v1 v2 v3 v4 v5 v6 v0 v1 28 v1 v2 16 v2 v3 12 v3 v4 22 v4 v5 25 v5 v0 10 v1 v6 14 v3 v6 18 v4 v6 24 */
相关文章推荐
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#数据结构之顺序表(SeqList)实例详解
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- Lua教程(七):数据结构详解
- C#算法函数:获取一个字符串中的最大长度的数字
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- 超大数据量存储常用数据库分表分库算法总结
- C#获取网页源代码的方法
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- LCL.VBS 病毒源代码
- 算法练习之从String.indexOf的模拟实现开始