相关定义
- 十字链表适用于
有向图
。 - 十字链表时有向图的另一种链式存储结构。(邻接表也是链式)
- 十字链表中:
对应于有向图中每个顶点都有一个结点,称此类结点为顶点结点
。
对应于有向图中每一条弧都有一个结点,称此类结点为弧结点
。
-
顶点结点
由 3 个域组成
1、data域
:存储和顶点相关的信息,如顶点的名称。
2、firstin域
:指向以该顶点为弧头的第一个弧结点。
3、firstout域
:指向以该顶点为弧尾的第一个弧结点。 -
弧结点
由5个域组成
1、尾域 / tailvex域
:表示弧尾所在顶点在图中的位置。
2、头域 / headvex域
: 表示弧头所在顶点在图中的位置。
3、链域 hlink域
: 指向弧头相同的下一条弧。
4、链域 tlink域
: 指向弧尾相同的下一条弧。
5、info域
: 指向该弧的相关信息。 -
十字链表示例(仅限有向图)
十字链表存储表示
#define MAX_VERTEX_NUM 20
//弧结点
typedef struct ArcBox
{
int tailvex, headvex; //该弧的尾和头顶点的位置
struct ArcBox *hlink, *tlink; //分别为弧头相同和弧尾相同的弧的链域
InfoType *info;
} ArcBox;
//顶点结点
typedef struct VexNode
{
VertexType data;
// 分别指向该顶点的第一条入弧和出弧
ArcBox *firstin, *firstout;
} VexNode;
// 表示一个有向图整体
typedef struct
{
VexNode xlist[MAX_VERTEX_NUM]; // 表头向量,各个顶点
int vexnum, arcnum; // 有向图的当前顶点数和弧数
} OLGraph;
代码实现:建立十字链表( n 个顶点和 e 条弧)
Status CreateDG(OLGraph &G)
{
// 采用十字链表存储表示,构造有向图 G(G.kind = DG)
scanf(&G.vexnum, &G.arcnum, &IncInfo);
// 初始化各个表头顶点
for(i=0; i<G.vexnum; ++i)
{
scanf(&G.xlist[i].data);
G.xlist[i].firstin = NULL;
G.xlist[i].firstout = NULL;
}
for(k=0; k<G.arcnum; k++)
{
scanf(&v1, &v2); // v1 和 v2 分别是一条弧的起点和终点
i = LocateVex(G, v1); // 确定 v1 和 v2 在 G 中的位置
j = LocateVex(G, v2);
p = (ArcBox *)malloc(sizeof(ArcBox));
*p = {i, j, G.xlist[j].firstin, G.xlist[i].firstout, NULL}; // 对弧结点的赋值
G.xlist[j].firstin = G.xlist[i].firstout = p; // 完成入弧和出弧链头的插入
if(IncInfo)
{
Input(*p->info);
}
}
}
- 十字链表的特点
1、仅适用于有向图
2、即容易找到以 vi 为尾的弧,也容易找到以 vi 为头的弧,因而容易求得顶点的出度和入度。
3、若输入的顶点信息
即为顶点的编号
,则建立邻接表的时间复杂度
为 O( n+e )
否则,需要通过查找才能得到顶点在图中位置,则时间复杂度为 O( n*e )