图的存储结构我们一共讲了五种,如图7-10-1所示,
    其中比较重要的是邻接矩阵和邻接表,它们分别代表着边集是用数组还是链表的方式存储。

    • 十字链表是针对有向图邻接表结构的优化,
    • 邻接多重表是针对无向图邻接表结构的优化。
    • 边集数组更多考虑的是对边的关注。

    用什么存储结构需要具体问题具体分析,
    通常稠密图,或读存数据较多,结构修改较少的图,用邻接矩阵要更合适,
    反之则应该考虑邻接表。
    image.png
    十字链表(Orthogonal List)是有向图的另一种链式存储结构。
    我们也可以把它看成是

    • 将有向图的邻接表和逆邻接表结合起来形成的一种链表。
    • 有向图中的每一条弧对应十字链表中的一个弧结点,同时有向图中的每个定点在十字链表中对应有一个结点,叫做定点结点。

    image.png
    image.png

    data firstin firstout

    其中

    • firstin表示入边表头指针,指向该顶点的入边表中第一个结点,
    • firstout表示出边表头指针,指向该顶点的出边表中的第一个结点。

    重新定义的边表结点结构如表所示。

    image.png
    其中

    • tailvex是指弧起点在顶点表的下标,
    • headvex是指弧终点在顶点表中的下标,
    • headlink是指入边表指针域,指向终点相同的下一条边,
    • taillink是指边表指针域,指向起点相同的下一条边。

    如果是网,还可以再增加一个weight域来存储权值。
    image.png
    image.png
    我们重点需要来解释虚线箭头的含义,它其实就是此图的逆邻接表的表示。

    • 对于v 0 来说,它有两个顶点v 1 和v 2 的入边。

    因此v 0 的firstin指向顶点v 1 的边表结点中headvex为0的结点,如图7-4-10右图中的①。
    接着由入边结点的headlink指向下一个入边顶点v 2 ,如图中的②。

    • 对于顶点v 1 ,它有一个入边顶点v 2 ,所以它的firstin指向顶点v 2 的边表结点中headvex为1的结点,如图中的③。
    • 顶点v 2 和v 3 也是同样有一个入边顶点,如图中④和⑤。

    十字链表的好处就是因为把邻接表和逆邻接表整合在了一起,这样既容易找到以v i 为尾的弧,也容易找到以v i 为头的弧,因而容易求得顶点的出度和入度。
    而且它除了结构复杂一点外,其实创建图算法的时间复杂度是和邻接表相同的O(n+e),因此,在有向图的应用中,十字链表是非常好的数据结构模型。

    image.png
    image.png