数据结构 邻接矩阵+邻接表+bfs+dfs+prim+Kruskal综合
来源:互联网 发布:ubuntu 安装到u盘 编辑:程序博客网 时间:2024/06/03 15:58
/*严格参照《数据结构(严蔚敏版)》2017.11.30by kk*/#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<queue>#include<math.h>#define infinity 0x3f3f3f3f#define maxsize 50using namespace std;typedef int VertexType;typedef int EdgeType;//下面是图的邻接矩阵的定义typedef struct{ EdgeType data;//弧的信息,比如可以用来标志这条边存不存在,权值多少 char infomation;//可以用来储存弧其他的信息} Matrix;typedef struct GraphM{ VertexType ver[maxsize];//顶点信息,如名字 Matrix arc[maxsize][maxsize];//邻接矩阵 int numVex,numEdge;//顶点个数,边的个数 int kind;//图的种类} GraphM;/*实际运用时如果弧上的信息不多(比如只有权值),其实就直接可以用用下面的方式定义typedef struct Graph{ int vertex[100]; int arc[100][100]; int num_ver,num_edge;} Mygraph;*///下面是邻接表的定义typedef struct ENode{ VertexType v;//节点的定义 int weight;//弧的权值 struct ENode *next;} ENode;typedef struct//顶点的定义{ VertexType v; ENode *first;} VerNode;typedef struct//图的定义{ VerNode VerList[maxsize];//顶点表 int numVer,numEdge;//顶点个数,边的个数 int kind;//图的种类} GraphL;int vis[maxsize];void createGraphMatrix(GraphM &g)//邻接矩阵建图{ int i,j; scanf("%d%d",&g.numVex,&g.numEdge); for(i=0; i<g.numVex; i++)scanf("%d",&g.ver[i]); for(i=0; i<g.numVex; i++) { for(j=0; j<g.numVex; j++) g.arc[i][j].data=infinity; } int x,y,w; for(i=0; i<g.numEdge; i++) { scanf("%d%d%d",&x,&y,&w); g.arc[x][y].data=w; g.arc[y][x].data=w;//如果是无向图就把这句加上 } for(i=0; i<g.numVex; i++) { for(j=0; j<g.numVex; j++) printf("%d ",g.arc[i][j].data); puts(""); }}void createGraphList(GraphL &g)//邻接表建图{ int i,j; ENode *e; scanf("%d%d",&g.numVer,&g.numEdge); for(i=0; i<g.numVer; i++) { scanf("%d",&g.VerList[i].v); g.VerList[i].first=NULL; } int x,y,w; for(i=0; i<g.numEdge; i++) { scanf("%d%d%d",&x,&y,&w); e=(ENode *)malloc(sizeof(ENode)); e->v=y; e->weight=w; e->next=g.VerList[x].first; g.VerList[x].first=e;//如果是无向图就把下面这段代码加上// e=(ENode *)malloc(sizeof(ENode));// e->v=x;// e->weight=w;// e->next=g.VerList[y].first;// g.VerList[y].first=e; }}void dfs_M(GraphM g,int x)//邻接矩阵dfs某个节点{ vis[x]=1; printf("%d ",g.ver[x]); for(int i=0; i<g.numVex; i++) if(vis[i]==0&&g.arc[x][i].data!=infinity)dfs_M(g,i);}void dfs_Matrix(GraphM g)//dfs整个表(即使不是连通图也可以){ memset(vis,0,sizeof(vis)); for(int i=0; i<g.numVex; i++) if(vis[i]==0)dfs_M(g,i);}void dfs_L(GraphL g,int x)//邻接表dfs某个节点{ vis[x]=1; printf("%d ",g.VerList[x].v); ENode *p; p=g.VerList[x].first; int tmp; while(p) { tmp=p->v; if(vis[tmp]==0) { dfs_L(g,tmp); } p=p->next; }}void dfs_List(GraphL g)//邻接表dfs整个图{ memset(vis,0,sizeof(vis)); ENode *p; for(int i=0; i<g.numVer; i++) { if(vis[i]==0) { dfs_L(g,i); } }}void bfs_M(GraphM g,int x)//邻接矩阵从x点开始广度优先遍历{ queue<int>que; que.push(x);//入队 vis[x]=1;//vis标记入口 int i,tmp; while(!que.empty()) { tmp=que.front(); printf("%d ",g.ver[tmp]); que.pop(); for(i=0; i<g.numVex; i++) { if(g.arc[tmp][i].data!=infinity&&vis[i]!=1) { que.push(i); vis[i]=1; } } }}void bfs_Matrix(GraphM g)//邻接矩阵bfs遍历整个图{ memset(vis,0,sizeof(vis)); for(int i=0; i<g.numVex; i++) if(vis[i]==0)bfs_M(g,i);}void bfs_L(GraphL g,int x)//邻接表从x点开始bfs遍历{ queue<int>que; ENode *p; que.push(x); vis[x]=1; int i,tmp; while(!que.empty()) { tmp=que.front(); printf("%d ",g.VerList[tmp].v); p=g.VerList[tmp].first; que.pop(); while(p) { if(vis[p->v]==0) { que.push(p->v); vis[p->v]=1; } p=p->next; } }}void bfs_List(GraphL g)//邻接表bfs整个图{ memset(vis,0,sizeof(vis)); for(int i=0; i<g.numVer; i++) if(vis[i]==0)bfs_L(g,i);}void miniSpanTree_Prim(GraphM g,int x)//prim算法求最小生成树{ int lowcost[maxsize]; //用来储存从现在已有的点出发到达为选择点的最短路径,这个最短不是说从某个点到达另外一个点的最短路径, //而是说就单条边的长度来说,也就是说这里面保存的值都是某条边的长度 int adjvex[maxsize]; int i,j,k; for(i=0; i<g.numVex; i++) if(i!=x)lowcost[i]=g.arc[x][i].data; lowcost[x]=0; //若lowcost[i]=0,说明i点已经被选中 for(i=0; i<g.numVex; i++) adjvex[i]=x;//所有的点最开始都是从i出发的 for(i=1; i<g.numVex; i++) { int Min=infinity; for(j=0; j<g.numVex; j++)//从lowcost数组中找出最短的边 { if(lowcost[j]!=0&&lowcost[j]<Min) { Min=lowcost[j]; k=j; } } printf("%d %d %d\n",adjvex[k],k,lowcost[k]); lowcost[k]=0; for(j=0; j<g.numVex; j++) { if(lowcost[j]!=0&&g.arc[k][j].data<lowcost[j])//更新lowcost数组和adjvex数组 { lowcost[j]=g.arc[k][j].data; adjvex[j]=k; } } //lowcost数组是用来存边长度和寻找最短边的 //而adjvex是用来记录路径的(就是这棵树的边是从哪个点到哪个点) }}int pre[maxsize];//用来记录根节点typedef struct{ int start; int last; int weight;} Edge;//相当于创建边集bool cmp( Edge a, Edge b){ return a.weight<b.weight;}//边集比较int Find(int x){ int r=x; while(r!=pre[r]) { r=pre[r]; } return r;}//这里其实用到了并查集的思想,找x的根节点//下面的函数中也有void MiniSpanTree_Kruskal(GraphM g){ Edge s[100]; int cnt=0; for(int i=0; i<g.numVex; i++) { for(int j=i; j<g.numVex; j++) { if(g.arc[i][j].data!=infinity) { s[cnt].start=i; s[cnt].last=j; s[cnt].weight=g.arc[i][j].data; ++cnt; } } } int i,j; sort(s,s+cnt,cmp);// for(i=0; i<g.numEdge; i++)// printf("%d %d %d\n",s[i].start,s[i].last,s[i].weight); //以上是将邻接矩阵转换成边集,并按权值从小到大排序 //pre[]数组初始化, pre[i]=i的意思是每个节点的跟节点都是自己本身 for(i=0; i<g.numVex; i++) pre[i]=i; int n,m; for(i=0; i<g.numEdge; i++) { n=Find(s[i].start); m=Find(s[i].last); //这里n,m分别是这条边两个节点的各自的根节点,如果m,n不等,那么说明 //m,n不在一个集合中,也就说明没有构成环 if(n!=m) { pre[n]=m;//将m节点及其孩子加入n所在的集合 printf("%d %d %d\n",s[i].start,s[i].last,s[i].weight); } }}int main(){// GraphL G;// createGraphList(G); GraphM G; memset(vis,0,sizeof(vis)); createGraphMatrix(G);// dfs_Matrix(G1);// dfs_Matrix(G); miniSpanTree_Prim(G,0); printf("\n"); MiniSpanTree_Kruskal(G);// bfs_L(G,2);// GraphL G2; l// createGraphList(G2);// dfs_List(G2); printf("\n"); return 0;}/*5 50 1 2 3 40 1 90 2 21 2 32 3 53 4 15 60 1 2 3 40 1 90 2 20 4 61 2 32 3 53 4 19 150 1 2 3 4 5 6 7 80 1 100 5 111 6 165 6 171 2 181 8 122 8 82 3 228 3 216 3 246 7 193 7 167 4 73 4 205 4 26*/
阅读全文
0 0
- 数据结构 邻接矩阵+邻接表+bfs+dfs+prim+Kruskal综合
- DFS和BFS 邻接矩阵和邻接表
- 图论 邻接链表存储 BFS DFS 拓扑排序 最小生成树 KRUSKAL PRIM
- 邻接表和邻接矩阵手写简洁代码DFS BFS
- java版 图的邻接表、邻接矩阵、BFS、DFS 实现
- 邻接表和邻接矩阵手写简洁代码DFS BFS
- 数据结构 学习笔记(七):图(上):图的表示方法(邻接表,邻接矩阵),遍历(DFS,BFS)
- 数据结构 邻接矩阵的BFS DFS
- 【裸MST:prim+邻接矩阵 / Kruskal+邻接表】hdu 1233 还是畅通工程
- 图的算法DFS、BFS、Prim、Kruskal
- 图的两种结构(邻接矩阵、邻接表)DFS、BFS算法
- 图的遍历(BFS、DFS的邻接矩阵和邻接表实现)
- 第七章 图(邻接矩阵和邻接表建立图并实现DFS、BFS)
- 数据结构实验图论:基于邻接矩阵/邻接表的广度优先搜索遍历(BFS)
- 【数据结构】DFS深度优先搜索(分别使用邻接矩阵、邻接表)
- 《数据结构》C++代码 邻接表与邻接矩阵
- 数据结构——邻接矩阵/邻接表
- 基于邻接矩阵和邻接表的两种方法实现无向图的BFS和DFS
- Ubuntu安装Java开发环境、Tomcat服务器
- jqweui Toast
- Java注释及文档注释
- XShell过期需要采购解决办法
- 关于点击事件的分析
- 数据结构 邻接矩阵+邻接表+bfs+dfs+prim+Kruskal综合
- flume 抽取图片文件数据写入到HDFS
- 编程之路小细节-数据库中表关联的主外键
- python study note
- Html代码中的标签换行造成间距问题
- The "yiisoft/yii2-composer" plugin was skipped because it requires a Plugin API version ("1.0.0") th
- typedef与typeof
- 主要浏览器调试工具
- vue获取当前点击事件