四种建图方法

来源:互联网 发布:中日友好医院 网络挂号 编辑:程序博客网 时间: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
原创粉丝点击