邻接矩阵,邻接表

第一种存图方式:邻接矩阵

开一个二维数组第一维存起点下标,第二维存终点下标

f[i][j]表示第i个点到第j个点之间的距离

无向图的两点之间存在边则需要同时对f[i][j]和f[j][i]进行赋值

这种方法的缺点是空间占用率大,大多数申请的空间是没用的

第二种存图方法:邻接表

我们发现,当图中的边数相对于顶点较少时,邻接矩阵是对存储空间的极大浪费。我们可以考虑对边或弧使用链式存储的方式来避免空间浪费的问题。回忆树结构的孩子表示法,将结点存入数组,并对结点的孩子进行链式存储,不管有多少孩子,也不会存在空间浪费问题。

应用这种思路,我们把这种数组与链表相结合的存储方法称为邻接表

邻接表是树与图结构的一般化存储方式, 邻接表可以看成“带有索引数组的多个数据链表”构成的结构集合。在这样的结构中存储的数据被分成若干类,每一类的数据构成一个链表。每一类还有一个代表元素,称为该类对应链表的“表头”。所有“表头”构成一个表头数组,作为一个可以随机访问的索引,从而可以通过表头数组定位到某一类数据对应的链表。

我们通过表头数组head可以定位到每一类所构成的链表进行遍历访问。

通过表头把所有的边分成不同的类,其中第x类就是从x出发的所有边。通过表头head[x] , 我们很容易定位到第x类对应的链表,从而访问从点x出发的所有边。

 上图是在邻接表中插入一张5个点、6条边的有向图之后的状态。这6条边按照插入的顺序依次是(1,2),(2,3),(2,5),(3,5),(5,4),(5,1)。head与next数组中保存的是“ver数组的下标”, 相当于指针, 其中0表示指向空。ver数组存储的是每条边的终点, 是真实的图数据;

head都初始化为-1吧便于跟下边的前向星对应

int head[1100001],next[1100001],to[1100001],dis[1100001];
int cnt=0;
//head是表头数组,next是指向的下一条边,to是表头所指向的点,dis是边权
void addroad(int x,int y,int z)
{
    to[++cnt]=y;dis[cnt]=z;
    next[cnt]=head[x];head[x]=cnt;//头插法
}
//和链式前向星一样
//遍历的方法
for(int i=head[x];i!=-1;i=next[i])
{
    int y=to[i];
    int z=dis[i];
}
#include<iostream>
using namespace std;
const int maxn=1001,maxm=100001;

struct Edge
{
 int next,to,dis;
}edge[maxm];

int head[maxn],num,n,m,u,v,d;
void add(int from,int to,int dis)
{
 edge[++num].next=head[from];
 edge[num].to=to;
 edge[num].dis=dis;
 head[from]=num;
}

int main()
{
 num=0;
 cin>>n>>m;//m为边数 n为结点数 
 for(int i=1;i<=m;i++)
 {
  cin>>u>>v>>d;
  add(u,v,d);
 }
 for(int i=1;i<=n;i++)
 {
  for(int j=head[i];j!=0;j=edge[j].next)
      cout<<edge[j].to<<edge[j].dis<<endl;   
 }
 return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值