• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
2014>
博客园    首页    新随笔    联系   管理    订阅  订阅
图的存储的4种形式

图的存储有4种形式:邻接矩阵,前向星,邻接表,链式前向星(属于邻接表)

1.链接矩阵

这个是我们最常用的,开一个map[i][j]

初始化 map[i][i]=0,map[i][j]=inf;

初始化需要o(n*n),建图 m

缺点 :遍历效率较低,并且不能存储重边,

初始化效率低;图的空间开销大。

2.前向星把边存在数组中,按照起点顺序排序;

用head数组去存以个个边为起点的第一个点。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct node
{
    int from;
    int to;
    int w;
}edge[10000];
bool cmp(node a,node b)
{
    if(a.to==b.to&&a.from==b.from)
        return a.w<b.w;
    if(a.from==b.from)
        return a.to<b.to;
    return a.from<b.from;
}
int head[10000];//记录以 vi开始的第一条边的位子;
int n,m;
int main()
{
  cin>>n>>m;//n个点,m条边
  memset(head,-1,sizeof head);
  for(int i=0;i<m;i++)
  {
      cin>>edge[i].from>>edge[i].to>>edge[i].w;
  }
  sort(edge,edge+m,cmp);
  head[0]=0;
  for(int i=1;i<m;i++)
  {
      if(edge[i].from!=edge[i-1].from)
        head[edge[i].from]=i;
  }//建图


  for(int i=1;i<=n;i++)
  {
      for(int k=head[i];edge[k].from==i&&k<m;k++)
      {
          cout<<edge[k].from<<" "<<edge[k].to<<" "<<edge[k].w<<endl;
      }
  }





    return 0;
}

时间复杂度mlogm 空间 m+n;

优点:可以应对点非常多的情况,可以存储重边;

缺点:不能判断任意2个顶点 vi和vj之间是否有边。

 

3.邻接表

邻接表 有3种实现:动态建表实现,使用stl中的vector模拟链表实现和静态建表实现。

① 动态建表

#include <iostream>

using namespace std;
struct EdgeNode
{
    int to;
    int w;
    EdgeNode *next;
};
struct VEdgeNode
{
    int from;
    EdgeNode *frist;
}alist[10000];

int main()
{

    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        EdgeNode *p=new EdgeNode();
        p->to=b;
        p->w=c;
        p->next=alist[a].frist;
        alist[a].frist=p;

    }
    for(int i=1;i<=m;i++)
    {
        for(EdgeNode *k=alist[i].frist;k!=NULL;k=k->next)
        {
            cout<<i<<" "<<k->to<<" "<<k->w<<endl;
        }
    }
    return 0;
}

 

② vector模拟链表

#include<iostream>
#include<vector>
using namespace std;
struct node
{
    int to;
    int w;
};
vector<node>map[10000];
int main()
{

    int n,m;
    cin>>n>>m;
   for(int i=1;i<=n;i++)
   {
       int a,b,c;
       cin>>a>>b>>c;
       node e;
       e.to=b;
       e.w=c;
       map[a].push_back(e);
   }
   for(int i=1;i<=m;i++)
   {
       for(vector <node>::iterator it=map[i].begin();it!=map[i].end();it++)
       {
          cout<<i<<" "<<it->to<<" "<<it->w<<endl;

       }
   }

    return 0;
}

 

③静态建表(链式前向星)

 

#include<iostream>
using namespace std;
int head[10000];
struct node
{
    int to;
    int w;
    int next;
}Edge[100000];

int main()
{

    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        head[i]=-1;
    }
   for(int i=1;i<=n;i++)
   {
       int a,b,c;
       cin>>a>>b>>c;
       Edge[i].to=b;
       Edge[i].w=c;
       Edge[i].next=head[a];
       head[a]=i;
   }
   for(int i=1;i<=m;i++)
   {
       for(int k=head[i];k!=-1;k=Edge[k].next)
       {
          cout<<i<<" "<<Edge[k].to<<" "<<Edge[k].w<<endl;

       }
   }

    return 0;
}

 

posted on 2017-08-09 14:59  2014>  阅读(624)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3