数据结构与算法-图论 邻接表【十五】

链式存储 (链式表示)

    上一话说的是邻接矩阵方式去存储图,这一话用链表去存储图
链式表表示法----【邻接表/ 邻接多重表 / 十字链表】

邻接表

    将所有的顶点数据仍然存放在一维数组内。
    这个一维数组比较特殊,顶点数组的每个元素都指向一个邻接点单链表。

咱们以上一个邻接矩阵用到的一个有向图和无向图为例:
在这里插入图片描述

无向图 的邻接表

第一个无向图的邻接表可以这样表示:

A邻接于B->C->NULL
B邻接于A ->C ->D ->NULL
C邻接于A ->D ->B->NULL
D邻接于B ->C ->NULL

    实际上邻接表是不唯一的,每一个顶点元素指向一个单链表,单链表的所有节点都是顶点元素的邻接点,顺序是可以随意更改的,比如上面的表中,A指向的单链表,B和C的顺序可以改变的。

    如果无向图n个顶点,e条边,那么用邻接表来存储这个图需要 n个头结点 和 2e个表结点。 更适合存储稀疏图。
     无向图 中顶点Vi的度为该顶点指向的单链表中的节点的个数。

问题:上面第一个无向图,5条边在邻接表里面存了两次,一共10个节点。

有向图 的邻接表

咱么以上面第二个有向图为例,邻接表的表示为

A邻接于B->NULLNULL
B邻接于C ->D->NULL
C邻接于A ->D->NULL
D邻接于NULL

特点: 该邻接表求顶点的出度容易,求入度困难。

  1. 顶点Vi的出度,就是这个顶点指向的单链表中节点的个数。
  2. 顶点Vi的入度, 必须要遍历非Vi顶点所指向的所有单链表。
有向图 的逆邻接表

咱们可以改变一下存储方式,上面的邻接表,每一个顶点元素指向的单链表存储的是该顶点的出度边指向的元素。 比如以第二个有向图的顶点 A 为例,他指向单链表中的元素为顶点B,为A指向B的弧尾。

咱们可以存储以A为入度边的弧尾的元素,这种类型的邻接表叫逆邻接表

还是以上面图中的第二个有向图为例:

A被邻接于C->NULL
B被邻接于A ->NULL
C被邻接于B ->NULL
D被邻接于B ->C->NULL

特点: 该邻接表求顶点的 入度容易,求出度困难。

  1. 顶点Vi的入度,就是这个顶点指向的单链表中节点的个数。
  2. 顶点Vi的出度, 必须要遍历非Vi顶点所指向的所有单链表。

邻接表的特点
  1. 很快速方便的找到某个顶点的“邻接点”
  2. 节约稀疏图(点多边少)的空间
  3. (针对无向图)求顶点的度很方便,求该顶点指向的单链表的节点个数即可
  4. (针对有向图)求顶点的出度方便,该顶点指向单链表的节点个数。【对于入度不方便,需要遍历所有单链表】
  5. (针对有向图)如果是逆邻接表,求顶点的入度方便,入度就为该顶点指向的单链表的节点个数。【对于出度不方便,需要遍历所有单链表】

对于有向图来说,邻接表和逆邻接表只能求出度或者入度容易,不能同时求出,可以将邻接表和逆邻接表结合起来改良为十字链表(存储的边节点个数不变,只是边节点存储的内容会多一些)。

对于无向图来说,求出度和入度容易,添加和删除麻烦,并且无向图邻接表的 边节点是存储了两份,所以改良为邻接多重表(将存储的边节点存储为一份,不会重复,边节点的内容也同样会多出来)


邻接矩阵与邻接表的区别
  1. 对于任意一个无向图,邻接矩阵是唯一的。但是邻接表不唯一,因为顶点指向的单链表各个节点的顺序是任意的,可以用头插法,也可以用尾插法。
  2. 邻接矩阵的空间复杂度为O(n^2), 邻接表的空间复杂度O(n+e) n为顶点个数,e为边的条数(也可以理解为所有指向的单链表中节点的个数)。
  3. 邻接矩阵多适用于稠密图(点多边多),邻接表多适用于稀疏图(点多边少 )
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值