对于有向图来说,邻接表(逆邻接表)是有缺陷的,其仅仅表述了关于出度(入度)的信息,如果想要了解另一方面就必须遍历整个图才可以得知。因此十字链表(Orthogonal List)应运而生,可以看做是邻接表和逆邻接表的结合。
- 顶点表结构如下:
data | firstin | firstout |
data:存放节点的相关数据信息;
firstin:表示入边表的头指针,指向该顶点的入边表的第一个节点;
firstout:表示出边表的头指针,指向该顶点的出边表的第一个节点;
- 边表结构如下:
tailvex | headvex | headlink | taillink | (weight) |
tailvex:弧尾(边的起点)在顶点表中的下标;
headvex:弧头(边的终点)在顶点表中的下标;
headlink:指向下一个弧头(边的终点)相同的边的指针;
taillink:指向下一个弧尾(边的起点)相同的边的指针;
weight:可以用来存放边的权重;
- 例
有向图如右图所示:
十字链表生成步骤如下:
- A->D:
将A的firstout指向该边节点,0和3分别表示A和D在顶点表中的下标;
将D的firstin指向该边节点;
- B->A:
将B的firstout指向该边节点,1和0分别表示B和A在顶点表中的下标;
将A的firstin指向该边节点; - B->C:
将上一条边B->A的taillink指向B->C,1和2分别表示B和C在顶点 表中的下标;
将C的firstin指向该边节点; - C->A:
将C的firstout指向该边节点,2和0分别表示C和A在顶点表中的下标;
由于B->A与C->A的弧头(边的终点)相同且都是A,因此将边B->A 的headlink指向边C->A; - C->D:
将上一条边C->A的taillink指向C->D,2和3分别表示C和D在顶点表中的 下标;
由于A->D与C->D的弧头(边的中点)相同且都是D,因此将边A->D的 headlink指向边C->D;
至此,有向图的十字链表生成结束。
从每个顶点节点开始有两条链表,一条是以该节点为弧头的链表,一条是以该节点为弧尾的链表,因而容易求得顶点的入度和出度。
代码存储结构如下:
typedef struct ArcBox // 弧的结构表示
{
int tailvex, headvex;
InfoType *info;
struct ArcBox *hlink, *tlink;
} VexNode;
typedef struct VexNode // 顶点的结构表示
{
VertexType data;
ArcBox *firstin, *firstout;
} VexNode;
typedef struct
{
VexNode xlist[MAX_VERTEX_NUM];// 顶点结点(表头向量)
int vexnum, arcnum;//有向图的当前顶点数和弧数
} OLGraph;