初学“邻接表(数组实现)”

本文介绍了邻接表数据结构的基础概念,通过《啊哈!算法》中的例子,阐述了如何使用数组存储边的信息,并通过first和next数组来管理顶点的边。内容包括边的编号、数组的初始化、first数组的用途以及next数组在构建链表结构中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

只是记录一下形成概念时候的胡思乱想。





从《啊哈!算法》里学的


 首先我们按照读入的顺序为每一条边进行编号1~m比如第一条边“1 4 9”的编号就是1,“1 3 7”这条边的编号是5

    这里uvw三个数组用来记录每条边的具体信息,即u[i]v[i]w[i]表示第i条边是从第u[i]号顶点到v[i]号顶点u[i]v[i],且权值为w[i]

091650h35zq3wgx30x3oe3.png



再用一个first数组来存储每个顶点其中一条边的编号以便待会我们来枚举每顶点所有的边(你可能存储其中一条边的编号就可以了?不可能吧,每个顶点都需要存储其所有边的编号才行吧!甭着急,继续往下看比如1号顶点有一条边是 “1 4 9”(该条边的编号是1),那么就将first[1]的值设为1。如果某个顶点i没有以该顶点为起始点的边,则将first[i]的值设为-1。现在我们来看看具体如何操作,初始状态如下。

091650zw3988qpj5iljj8g.png

 

        咦?上图中怎么多了一个next数组,有什么作用呢?不着急,待会再解释,现在先读入第一条边“1 4 9”。

        读入第1条边1 4 9,将这条边的信息存储到u[1]v[1]w[1]同时这条边赋予一个编号因为这条边是最先读入的,存储在uvw数组下标为1的单元格中,因此编号就是1。这条边的起始点是1号顶点,因此将first[1]的值设为1

        另外这条编号为1的边1号顶点u[1]为起始点第一条边,所以next[1]的值设为-1。也是说,如果当前这条编号为i的边,是我们发现的u[i]起始点的第一条边,就将next[i]的值设为-1(貌似的这个next数组很神秘啊⊙_




想法概念(类比):有n个顶点(n等公民),前来报到,第i个公民的编号是i,first公寓有n等公民的专用房间,next公寓有m个房间,无人则是


091651kwo5g0aycy07wfwd.png第1(i=1)个人来了,给他编号为1,准备next【1】的钥匙,发现他是一等公民(u[i]=1),如果first[ u[ i ] ]有人(first[ u[ i ] ] > 0),就让他搬去next[ i ](此时编号i=1),此时first[1]=-1,所以不用搬走,直接让i号去first公寓的一等公民专用房间,next【1】“没人领”

091651df28foy9ct7fl7qf.png
第3(i=3)个人来了,给他编号为3,准备next【3】的钥匙,发现他是一等公民(u[3]=1),first[ u[ i ] ]有人(first[ 1 ] = 1),就让他(1号)搬去next【3】(此时编号i=3),然后让3号去first公寓的一等公民专用房间first[1],

091652rtjh5qe2211eee58.png


int n,m,i;
//u、v和w的数组大小要根据实际情况来设置,要比m的最大值要大1
int u[6],v[6],w[6];
//first和next的数组大小要根据实际情况来设置,要比n的最大值要大1
int first[5],next[5];
scanf("%d %d",&n,&m);
//初始化first数组下标1~n的值为-1,表示1~n顶点暂时都没有边
for(i=1;i<=n;i++)
    first[i]=-1;
for(i=1;i<=m;i++)
{
    scanf("%d %d %d",&u[i],&v[i],&w[i]);//读入每一条边
    //下面两句是关键啦
    next[i]=first[u[i]];
    first[u[i]]=i;
}
  //遍历1号顶点所有边的代码如下。

 
k=first[1];// 1号顶点其中的一条边的编号(其实也是最后读入的边)
while(k!=-1) //其余的边都可以在next数组中依次找到
{
    printf("%d %d %d\n",u[k],v[k],w[k]);
    k=next[k];
}
   //遍历每个顶点的所有边的代码如下。

for(i=1;i<=n;i++)
{
    k=first[i];
    while(k!=-1)
    {
        printf("%d %d %d\n",u[k],v[k],w[k]);
        k=next[k];
    }
}




  可以发现使用邻接表来存储图的时间空间复杂度是O(M),遍历每一条边的时间复杂度是也是O(M)。如果一个图是稀疏图的话,M要远小于N2。因此稀疏图选用邻接表来存储要比邻接矩阵来存储要好很多。



乱想完后才注意到链表结构。。2333333





代码完整示范:【啊哈!算法】算法8:图还可以这样存——邻接表的数组实现


091651kwo5g0aycy07wfwd.png
091651df28foy9ct7fl7qf.png
091652rtjh5qe2211eee58.png


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值