_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)算法求最小生成 ...
随机推荐
- 【微信】微信小程序 微信开发工具 创建js文件报错 pages/module/module.js 出现脚本错误或者未正确调用 Page()
创建报错pages/module/module.js 出现脚本错误或者未正确调用 Page() 解决方法: 在js文件中添加 Page({ })
- Maven配置Spring+Hibernate Shiro权限控制项目
前言:在Eclipse中安装好Maven插件,然后创建一个Sample项目.在Eclipse中检出Shiro的官方演示样例.地址http://svn.apache.org/repos/asf/shir ...
- tensorflow TensorArray 代码例子
import tensorflow as tf import numpy as np B=3 D=4 T=5 tf.reset_default_graph() xs=tf.placeholder(sh ...
- Myeclipse 编译等级
1.Java compiler level does not match the version of the installed Java project facet. 问题描述:编译等级不匹配 解 ...
- 机器学习第4课:多变量线性回归(Linear Regression with Multiple Variables)
4.1 多维特征 目前为止,我们探讨了单变量/特征的回归模型,现在我们对房价模型增加更多的特征, 例如房间数楼层等,构成一个含有多个变量的模型,模型中的特征为(x1,x2,...,xn).
- Tomcat7.0源代码分析——启动与停止服务原理
前言 熟悉Tomcat的project师们.肯定都知道Tomcat是怎样启动与停止的. 对于startup.sh.startup.bat.shutdown.sh.shutdown.bat等脚本或者批处 ...
- bitcoin-qt忘记密码
客户端有钱包加密功能,输入密码可以增强安全性. 但是,如果你把钱包文件弄丢了,那即使设了密码,币也会丢. 关闭bitcoin-qt,把钱包文件wallet.dat 剪到其他地方(但不要删除),然后重新 ...
- 倍福TwinCAT(贝福Beckhoff)基础教程2.0 TwinCAT常用快捷键
F5:运行程序 CTRL+F5:停止运行当前程序 F12:登出 F11:登录 CTRL+F7:强制写入数值 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.you ...
- Github 的一个免费编程书籍列表
Index Ada Agda Alef Android APL Arduino ASP.NET MVC Assembly Language Non-X86 AutoHotkey Autotools A ...
- 《Microsoft Sql server 2008 Internals》读书笔记--第六章Indexes:Internals and Management(1)
<Microsoft Sql server 2008 Internals>索引文件夹: <Microsoft Sql server 2008 Internals>读书笔记--文 ...