_DataStructure_C_Impl:图的最小生成树
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char VertexType[4];
typedef char InfoPtr;
typedef int VRType;
#define INFINITY 10000 //定义一个无限大的值
#define MaxSize 50 //最大顶点个数
typedef enum{DG,DN,UG,UN}GraphKind; //图的类型:有向图、有向网、无向图和无向网 typedef struct{
VRType adj; //对于无权图,用1表示相邻,0表示不相邻;对于带权图,存储权值
InfoPtr *info; //与弧或边的相关信息
}ArcNode,AdjMatrix[MaxSize][MaxSize];
//图的类型定义
typedef struct{
VertexType vex[MaxSize]; //用于存储顶点
AdjMatrix arc; //邻接矩阵,存储边或弧的信息
int vexnum,arcnum; //顶点数和边(弧)的数目
GraphKind kind; //图的类型
}MGraph;
//记录从顶点集合U到V-U的代价最小的边的数组定义
typedef struct{
VertexType adjvex;
VRType lowcost;
}closeedge[MaxSize];
//在顶点向量中查找顶点v,找到返回在向量的序号。否则返回-1
int LocateVertex(MGraph N,VertexType v){
int i;
for(i=0;i<N.vexnum;++i)
if(strcmp(N.vex[i],v)==0)
return i;
return -1;
}
//採用邻接矩阵表示法创建有向网N
void CreateGraph(MGraph *N){
int i,j,k,w,InfoFlag,len;
char s[MaxSize];
VertexType v1,v2;
printf("请输入有向网N的顶点数,弧数,弧的信息(是:1,否:0): ");
scanf("%d,%d,%d",&(*N).vexnum,&(*N).arcnum,&InfoFlag);
printf("请输入%d个顶点的值(<%d个字符):\n",N->vexnum,MaxSize);
for(i=0;i<N->vexnum;++i) //保存网的各个顶点
scanf("%s",N->vex[i]);
for(i=0;i<N->vexnum;i++) //初始化邻接矩阵
for(j=0;j<N->vexnum;j++){
N->arc[i][j].adj=INFINITY;
N->arc[i][j].info=NULL; //弧的信息初始化为空
}
printf("请输入%d条弧的弧尾 弧头 权值(以空格作为间隔): \n",N->arcnum);
for(k=0;k<N->arcnum;k++){
scanf("%s%s%d",v1,v2,&w); //输入两个顶点和弧的权值
i=LocateVertex(*N,v1);
j=LocateVertex(*N,v2);
N->arc[i][j].adj=w;
if(InfoFlag){ //假设弧包括其他信息
printf("请输入弧的相关信息: ");
gets(s);
len=strlen(s);
if(len){
N->arc[i][j].info=(char *)malloc((len+1)*sizeof(char));
strcpy(N->arc[i][j].info,s);
}
}
}
N->kind=DN; //图的类型为有向网
}
//销毁网N
void DestroyGraph(MGraph *N){
int i,j;
for(i=0;i<N->vexnum;i++) //释放弧的相关信息
for(j=0;j<N->vexnum;j++)
if(N->arc[i][j].adj!=INFINITY) //假设存在弧
if(N->arc[i][j].info!=NULL){ //假设弧有相关信息,释放该信息所占用空间
free(N->arc[i][j].info);
N->arc[i][j].info=NULL;
}
N->vexnum=0; //将网的顶点数置为0
N->arcnum=0; //将网的弧的数目置为0
}
//
void DisplayGraph(MGraph N){
int i,j;
printf("有向网具有%d个顶点%d条弧。顶点依次是: ",N.vexnum,N.arcnum);
for(i=0;i<N.vexnum;++i) //输出网的顶点
printf("%s ",N.vex[i]);
printf("\n有向网N的:\n"); //输出网N的弧
printf("序号i=");
for(i=0;i<N.vexnum;i++)
printf("%8d",i);
printf("\n");
for(i=0;i<N.vexnum;i++)
{
printf("%8d",i);
for(j=0;j<N.vexnum;j++)
printf("%8d",N.arc[i][j].adj);
printf("\n");
}
}
//将lowcost的最小值的序号返回
int MiniNum(closeedge edge,MGraph G){
int i=0,j,k,min;
while(!edge[i].lowcost)
i++;
min=edge[i].lowcost;//第一个不为0的值
k=i;
for(j=i+1;j<G.vexnum;j++)
if(edge[j].lowcost>0&&edge[j].lowcost<min){ //将最小值相应的序号赋值给k
min=edge[j].lowcost;
k=j;
}
return k;
}
//利用普里姆算法求从第u个顶点出发构造网G的最小生成树T
void Prim(MGraph G,VertexType u){
int i,j,k;
closeedge closedge;
k=LocateVertex(G,u); //k为顶点u相应的序号
for(j=0;j<G.vexnum;j++){ //数组初始化
strcpy(closedge[j].adjvex,u);
closedge[j].lowcost=G.arc[k][j].adj;
}
closedge[k].lowcost=0; //初始时集合U仅仅包括顶点u
printf("无向网的最小生成树的各条边各自是:\n");
for(i=1;i<G.vexnum;++i){ //选择剩下的G.vexnum-1个顶点
k=MiniNum(closedge,G); //k为与U中顶点相邻接的下一个顶点的序号
printf("(%s-%s)\n",closedge[k].adjvex,G.vex[k]); //输出生成树的边
closedge[k].lowcost=0; //第k顶点并入U集
for(j=0;j<G.vexnum;++j)
if(G.arc[k][j].adj<closedge[j].lowcost){ //新顶点增加U集后又一次将最小边存入到数组
strcpy(closedge[j].adjvex,G.vex[k]);
closedge[j].lowcost=G.arc[k][j].adj;
}
}
}
void main(){
MGraph N;
printf("创建一个无向网:\n");
CreateGraph(&N);
DisplayGraph(N);
Prim(N,"A");
DestroyGraph(&N);
system("pause");
}
_DataStructure_C_Impl:图的最小生成树的更多相关文章
- C++编程练习(10)----“图的最小生成树“(Prim算法、Kruskal算法)
1.Prim 算法 以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 2.Kruskal 算法 直接寻找最小权值的边来构建最小生成树. 比较: Kruskal 算法主要是针对边来展开,边数 ...
- "《算法导论》之‘图’":最小生成树(无向图)
本文主要参考自<算法>. 加权图是一种为每条边关联一个权值或是成本的图模型.这种图能够自然地表示许多应用.在一幅航空图中,边表示航线,权值则可以表示距离或是费用.在一幅电路图中,边表示导线 ...
- 无向带权图的最小生成树算法——Prim及Kruskal算法思路
边赋以权值的图称为网或带权图,带权图的生成树也是带权的,生成树T各边的权值总和称为该树的权. 最小生成树(MST):权值最小的生成树. 生成树和最小生成树的应用:要连通n个城市需要n-1条边线路.可以 ...
- hdu 1233:还是畅通工程(数据结构,图,最小生成树,普里姆(Prim)算法)
还是畅通工程 Time Limit : 4000/2000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submis ...
- 图的最小生成树——Kruskal算法
Kruskal算法 图的最小生成树的算法之一,运用并查集思想来求出最小生成树. 基本思路就是把所有边从小到大排序,依次遍历这些边.如果这条边所连接的两个点在一个连通块里,遍历下一条边,如果不在,就把这 ...
- 图的最小生成树(java实现)
1.图的最小生成树(贪心算法) 我两个算法的输出都是数组表示的,当前的索引值和当前索引对应的数据就是通路,比如parent[2] = 5;即2和5之间有一个通路,第二个可能比较好理解,第一个有点混乱 ...
- Kruscal算法求图的最小生成树
Kruscal算法求图的最小生成树 概述 和Prim算法求图的最小生成树一样,Kruscal算法求最小生成树也用到了贪心的思想,只不过前者是贪心地选择点,后者是贪心地选择边.而且在算法的实现中,我 ...
- 图的最小生成树(Prim、Kruskal)
理论: Prim: 基本思想:假设G=(V,E)是连通的,TE是G上最小生成树中边的集合.算法从U={u0}(u0∈V).TE={}开始.重复执行下列操作: 在所有u∈U,v∈V-U的边(u,v)∈E ...
- 图->连通性->最小生成树(克鲁斯卡尔算法)
文字描述 上一篇博客介绍了最小生成树(普里姆算法),知道了普里姆算法求最小生成树的时间复杂度为n^2, 就是说复杂度与顶点数无关,而与弧的数量没有关系: 而用克鲁斯卡尔(Kruskal)算法求最小生成 ...
随机推荐
- Vue.js 2.0源码解析之前端渲染篇
一.前言 Vue.js框架是目前比较火的MVVM框架之一,简单易上手的学习曲线,友好的官方文档,配套的构建工具,让Vue.js在2016大放异彩,大有赶超React之势.前不久Vue.js 2.0正式 ...
- 【转】C++调用Matlab的.m文件
原文地址 Matlab是一个强大的数学计算/仿真工 具,其内置了很多实用的现成的函数,而且我们经常也自己定义很多m函数.但在很多情况下,我们不得不使用VC编程.那么,如何在VC中利用matla ...
- ASIHTTPRequest框架使用总结系列之阿堂教程5(上传数据)
在上篇文章中,阿堂和网友们分享了如何用ASIHTTPRequest框架下载数据的实例,本篇阿堂将数据介绍如何用ASIHTTPRequest框架上传数据的应用实例. 数据上传是通过ASIHT ...
- 如何开启Linux双网卡的转发功能
原文地址:http://blog.csdn.net/lllzd/article/details/8587624 说明:在<把arm开发板做成USB网卡(RNDIS /Ethernet Gadge ...
- flask控制上传文件的大小
1.flask控制上传文件的大小的方案是全局控制:http://docs.jinkan.org/docs/flask/patterns/fileuploads.html from flask impo ...
- MySQL的左外连接
代码: select t1.descid, IFNULL(t2.cnt,) as countnew, t1.description from uosdesc t1 left outer join t2 ...
- S4:装饰模式 Decorator
动态的给一个对象添加额外的一些职责,就增加功能而言,比继承更具灵活性. 如果仅有一个ConcreateComponent,也可以让Decorator继承ConcreateComponent来实现装饰功 ...
- MFC对话框贴图基础上控件Stasic变成透明的
对应WM_CTLCOLOR函数 加入下面代码: HBRUSH CMFCApplication2Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) ...
- jQuery.delegate() 函数详解
delegate()函数用于为指定元素的一个或多个事件绑定事件处理函数. 此外,你还可以额外传递给事件处理函数一些所需的数据. 即使是执行delegate()函数之后新添加的元素,只要它符合条件,绑定 ...
- TCP/IP协议分析(推荐)
一;前言 学习过TCP/IP协议的人多有一种感觉,这东西太抽象了,没有什么数据实例,看完不久就忘了.本文将介绍一种直观的学习方法,利用协议分析工具学习TCP/IP,在学习的过程中能直观的看到数据的具体 ...