四种建图方法
来源:互联网 发布:中日友好医院 网络挂号 编辑:程序博客网 时间:2024/05/01 23:05
四种常见的建图方法
1.邻接矩阵
直接开一个N*N的矩阵如果i,j相连则将二维矩阵赋值,否则则为INF,虽然简单直观但是遍历效率过低,并且不能存储重边,遇到点较稀疏的图时空间利用率过低,时间复杂度为O(N*N)
2.前向星
将所有边排序并记录每个顶点第一条边的位置,从而实现的存储和遍历。可以储存重边但是不可以直接判断两个节点是否相连,时间复杂度为O(M*logM)
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;int N,M;struct node{ int from,to,w;}G[105];int head[105];bool cmp(node a,node b){ if(a.from==b.from&&a.to==b.to) return a.w<b.w; if(a.from==b.from) return a.to<b.to; return a.from<b.from;} //排序使找到每个节点int main(){ int i,j,k; scanf("%d%d",&N,&M); for(i=0;i<M;i++) scanf("%d%d%d",&G[i].from,&G[i].to,&G[i].w); memset(head,-1,sizeof(head)); sort(G,G+M,cmp); head[G[0].from]=0; for(i=1;i<M;i++) if(G[i].from!=G[i-1].from) head[G[i].from]=i; //每个节点第一条边的位置 for(i=1;i<=N;i++){ //图的遍历 for(k=head[i];G[k].from==i&&k<M;k++) //因为涉及排序所以复杂度为O(M*logM) printf("%d %d %d\n",G[k].from,G[k].to,G[k].w); } return 0;}
3.邻接表
将每一个顶点所连的边组成一条单链表,每条单链表称为这个节点的邻接表,有两种实现方式,时间复杂度为O(M)
(1).动态链表
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;int N,M;struct node{ int to,w; node *next;};struct edge{ node *first;}G[105];int main(){ int i,j,x,y,z; scanf("%d%d",&N,&M); for(i=0;i<M;i++){ scanf("%d%d%d",&x,&y,&z); node *p=new node; p->to=y; p->w=z; p->next=G[x].first; //每条边连在当前节点的前一条边上 G[x].first=p; //形成一个链式储存结构,first为当前节点的最后 } //一条边 node *k; for(i=1;i<=N;i++){ //图的遍历 for(k=G[i].first;k!=NULL;k=k->next) printf("%d %d %d\n",i,k->to,k->w); } return 0;}(2).用vector实现
#include <vector>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;int N,M;struct node{ int to,w;};vector<node> G[105];int main(){ int i,j,x,y,z; scanf("%d%d",&N,&M); for(i=0;i<M;i++){ scanf("%d%d%d",&x,&y,&z); G[x].push_back((node){y,z}); } for(i=1;i<=N;i++){ for(j=0;j<G[i].size();j++) printf("%d %d %d\n",i,G[i][j].to,G[i][j].w); } return 0;}4.链式前向星
通过数组模拟邻接表,是建图和遍历效率较高的一种方法,时间复杂度为O(M)
#include <vector>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;int N,M;struct node{ int to,w,next;}G[105];int head[105];int main(){ int i,j,x,y,z; scanf("%d%d",&N,&M); memset(head,-1,sizeof(head)); for(i=0;i<M;i++){ scanf("%d%d%d",&x,&y,&z); G[i].to=y; G[i].w=z; G[i].next=head[x]; head[x]=i; //与前向星相同,当前边连接当前节点的 } //前一条边 for(i=1;i<=N;i++){ for(j=head[i];j!=-1;j=G[j].next) //head[i]为i节点最后一条边的位置 printf("%d %d %d\n",i,G[j].to,G[j].w); } return 0;}
0 0
- 四种建图方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- 方法
- MySQL - 海量数量下的查询效率提升
- 常见服务器类型及其简单介绍
- https://sci-hub.io/ 吊炸天,各种论文随便下
- Windows下远程Linux图形化Eclipse
- finger 指令
- 四种建图方法
- sql查询数据库的常用优化方法
- 使用Weka进行数据挖掘(Weka教程八)Weka分类评价Evaluation输出分析
- 如何将货币字符串转换为double与jQuery或JavaScript?
- CAS(Central Authentication Service)——windows上简单搭建及测试
- C指针解析 右左法则----复杂指针解析
- python 模块加载机制
- 晓月_【游戏参考】九阴真经
- 如何反编译APK修改成自己想要的并打包运行