十字链表
你会发现,要表示一个有向图,因为有 出度 和 入度 ,需要两个邻接表:邻接表和逆邻接表。
其实我们可以把这两个表整合在一起,也就是十字链表(Orthogonal List)。
我们依然需要构造一种结构体A,用结构体A的数组来存放所有顶点-我们其实可以把它叫做 顶点表。
我们构造的结构体A如下:
data | firstin | firstout |
构造结构体B,用结构体B来记录与这个顶点 用边邻接的 顶点的相关信息,我们把它叫做 边表。
tailvex | headvex | headlink | taillink |
在顶点表的每个顶点中,我们用firstin去指向和这个顶点有关的入边表的第一个元素(指向这个顶点的边,叫做入边),叫做入边表头指针。
用firstout去指向和这个顶点有关的出边表的第一个元素(从这个顶点指向别的顶点的边,叫做出边),叫做出边表头指针。
data用于存放这个顶点的数据。
在边表的每个元素中,tailvex是弧的起点在顶点表的数组下标,headvex是弧终点在顶点表的数组下标。headlink(入边表指针域)指向边表中和这个元素的弧终点相同的下一个元素,taillink(出边表指针域)指向边表中和这个元素的弧起点相同的下一个元素。
如果是网(每个边都带有权值的图),还可以增加一个weight域来存储权值。
举一个具体的例子如下图:
图-十字链表示例
V0,V1,V2,V3四个顶点,对应的数组中的下标分别为0,1,2,3。我们也可以看出,五条边分别为 0-3,1-0,1-2,2-1,2-0(需要考虑方向)。在构造边表时,你会注意到,对于边表中的一个元素,它作为某个顶点的出边时,也一定是对应的另一个顶点的入边。
邻接多重表
十字链表主要用于有向图。对于无向图,当我们对这个图的使用侧重于边的处理时,邻接多重表是一个更好的选择。
我们新建边表所使用的结构体B 如下:
ivex | ilink | jvex | jlink |
其中ivex,jvex是这条边所连接的两个顶点在顶点数组中的下标。ilink指向 ivex的另一条边,jlink指向 jvex的另一条边。 或者更机械化的说法,ilink指向的下一个元素的jvex与当前元素的ivex相同。jlink指向的下一个元素的ivex与当前元素的jvex相同。
图-邻接多重表的示例
V0,V1,V2,V3四个顶点,对应的数组中的下标分别为0,1,2,3。我们也可以看出,五条边分别为 0-1,0-2,1-2,2-3,3-0(没有方向的区别)。
边集数组
还有一种表达方式,边集数组。
图-边集数组的示例
这种表示方法从结果的展示上来看非常直观容易理解。但是要找到对应的顶点所有的边,他需要对数组进行遍历。所以这种方法,似乎更适合需要对边进行逐一操作的场合。
未完。
原文地址:https://www.cnblogs.com/OranBlog/p/8427168.html