图论-图的存储(邻接表)探究

一. vector形式

1. 特性分析
  • 优点:代码简单,均摊时间代价也不是很大
  • 缺点:性能确实没那么高,当考虑边的权值是还需另外定义struct,遍历也不再方便
  • 适用情形:只考虑连通性的稀疏图
2. 代码实现
#include <vector>

using namespace std;
const int maxn=2e4+10;

int n,m;
vector<int> edges[maxn];

//图的录入
int u,v;
scanf("%d%d",&u,&v);
edges[u].push_back(v);

//边的遍历
for(int v:edges[u)
{
    //访问边 <u,v>
    //...
}

二. 链式向前星(模拟链表)

1. 特性分析
  • 优点:比链表代码简单,性能高、空间占用小,考虑边的权值时仍很方便
  • 缺点:实现不如vector形式简单
  • 适用情形:考虑边的权值时的稀疏图
  • 备注:特别地,当处理最大网络流问题时,使用链式向前星可以方便地回去正向边和对应的反向边
2. 代码实现
using namespace std;
const int N=1e4+10,E=2e5+10,INF=1<<30;//注意边集应为双倍!!!

int n,m,s,t;
int idx=2,first[N],nxt[E],to[E],val[E];

//图的录入
inline void addE(int u,int v,int w)
{
    to[idx]=v,val[idx]=w;
    nxt[idx]=first[u];
    first[u]=idx++;
}

//边的遍历
for(int p=first[u];p;p=nxt[p])
{
    int v=to[p],w=val[p];
    //访问边 <u,v,w>
    //...
}

三. 邻接链表

1. 特性分析
  • 优点:结构严谨,看着清楚
  • 缺点:实现比较复杂,容易写错
  • 适用情形:一般不使用(适合工程中使用)
2. 代码实现
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

struct ArcNode
{
    int u,v,w;
    ArcNode * next;

    ArcNode(){}
    ArcNode(int _u,int _v,int _w,ArcNode * _next):u(_u),v(_v),w(_w),next(_next){}
};

struct VNode
{
    ArcNode * first_arc;
};

struct Graph
{
    int n;
    int m;
    
    VNode * vec;
    

    Graph(int _n,int _m)
    {
        n=_n,m=_m;
        vec=new VNode[n+1];
        for(int i=0;i<=n;i++)
            vec[i].first_arc=nullptr;
    }

    ~Graph()
    {
        for(int i=0;i<=n;i++)
        {
            ArcNode * arc=vec[i].first_arc;
            while(arc)
            {
                vec[i].first_arc=arc->next;
                delete arc;
                arc=vec[i].first_arc;
            }
            delete [] vec;
        }
    }

    void create()
    {
        for(int i=1;i<=m;i++)
        {
            int u,v,w;
            cin>>u>>v>>w;
            ArcNode * newNode=new ArcNode(u,v,w,vec[u].first_arc);
            vec[u].first_arc=newNode;
        }
    }

    void show()
    {
        for(int i=1;i<=n;i++)
        {
            cout<<i<<"==>";
            ArcNode * arc=vec[i].first_arc;
            while(arc)
            {
                cout<<arc->v<<" ";
                arc=arc->next;
            }
            cout<<endl;
        }
    }
};

int main()
{
    int n,m;
    cin>>n>>m;
    Graph graph(n,m);
    graph.create();
    graph.show();
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值