图的存储结构-十字链表

图的存储结构-十字链表

十字链表(Orthogonal List)是有向图的一种链式存储结构。可以看成是将有向图的邻接表和逆邻接表结合起来得到的一种链表。在十字链表中,对应于有向图中每一条弧有一个结点,对应于每个顶点也有一个结点。

十字链表的结构

顶点结点

顶点结点

typedef string InfoType ;
typedef string VertexType;

typedef struct VexNode{
    
    
    VertexType data; //顶点的数据域
    ArcBox *firstIn; //指向该顶点的第一条入弧
    ArcBox *firstOut; //指向该顶点的第一条出弧
}VexNode;

弧结点

弧结点

typedef struct ArcBox{
    
    
    int tailVex; //该弧的尾顶点的位置
    int headVex; //该弧的头顶点的位置
    struct ArcBox * hLink; //弧头相同的弧的链域
    static ArcBox * tLink; //弧尾相同的弧的链域
    InfoType info; //弧的相关信息
}ArcBox;

十字链表结点:

#define MAX_VERTEX_BUM 20
typedef struct {
    
    
    VexNode xList[MAX_VERTEX_BUM]; //表头向量
    int vexNum; //图的顶点个数
    int arcNum; //图的边数
}OLGraph;

有向图十字链表

在弧结点中有5个域:其中尾域(tailvex)和头域(headvex)分别指示弧尾和弧头这两个顶点在图中的位置,链域hlink指向弧头相同的下一条弧,而链域tlink指向弧尾相同的下一条弧,info域指向该弧的相关信息。弧头相同的弧在同一链表上,弧尾相同的弧也在同一链表上。
它们的头结点即为顶点结点,它由3个域组成:其中data域存储和顶点相关的信息,如顶点的名称等;firstIn和firstOut为两个链域,分别指向以该顶点为弧头或弧尾的第一条弧结点。如下图:
在这里插入图片描述
若将有向图的邻接矩阵看成稀疏矩阵的话,则十字链表也可以看成是邻接矩阵的链式存储结构,在图的十字链表中,弧结点所在的链表非循环链表,结点之间相对位置自然形成,不一定按顶点序号有序,表头结点即顶点,它们之间不是链接,而是顺序存储。

使用十字链表法创建一个有向图

OLGraph CreateOLG() {
    
    
    OLGraph G;
    cout << "输入顶点的总数,边的总数 G(V,E)" << endl;
    cin >> G.vexNum >> G.arcNum;  //输入总顶点数,总边数

    for (int vi = 0; vi < G.vexNum; ++vi) {
    
    
        cout << "输入顶点" << vi << "的值:" << endl;
        cin >> G.xList[vi].data;    //输入顶点的值
        G.xList[vi].firstIn = NULL; //初始化入弧表
        G.xList[vi].firstOut = NULL; //初始化出弧表
    }

    int i = -1, j = -1;
    for (int k = 0; k < G.arcNum; ++k) {
    
    
        VertexType v1, v2;
        cout << "请输入边的值 (vi,vj) " << endl;
        cin >> v1 >> v2; //输入一条边依附的两个顶点
        i = LocateVex(G, v1); //获得v1 在G.xList[]中的位置
        j = LocateVex(G, v2); //获得v2 在G.xList[]中的位置

        ArcBox *p1 = new ArcBox;  //生成一个新的边 *p1
        p1->tailVex = i; //弧尾的顶点位置
        p1->headVex = j; //弧头的顶点位置
        p1->tLink = G.xList[i].firstOut;
        p1->hLink = G.xList[j].firstIn;
        G.xList[i].firstOut = p1;
        G.xList[j].firstIn = p1;

    }
    return G;
}
/**
 * 若图G中存在顶点u,则返回该顶点在图中的位置;否则返回其它信息;
 */
int LocateVex(OLGraph G, VertexType u) {
    
    
    int i;
    for (i = 0; i < G.vexNum; ++i)
        if (u == G.xList[i].data)
            return i;
    return -1;
}

过程图解

1.初始化图G(V,E);

		cin >> G.xList[vi].data;    //输入顶点的值
        G.xList[vi].firstIn = NULL; //初始化入弧表
        G.xList[vi].firstOut = NULL; //初始化出弧表

在这里插入图片描述
2.创建一个边结点

 		ArcBox *p1 = new ArcBox;  //生成一个新的边 *p1
        p1->tailVex = i; //弧尾的顶点位置
        p1->headVex = j; //弧头的顶点位置

在这里插入图片描述
3.将边结点加入十字链表
先将边结点的插入弧尾相同的链表表头;

 		p1->tLink = G.xList[i].firstOut;

在这里插入图片描述
在把边结点的插入弧头相同的链表表头;

		p1->hLink = G.xList[j].firstIn;

在这里插入图片描述
最后让 弧尾顶点的第一条出弧、弧头顶点的第一条入弧,指向新加入的边界点;

        G.xList[i].firstOut = p1;
        G.xList[j].firstIn = p1;

在这里插入图片描述
4.继续加入先得边结点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/QQ657205470/article/details/127361701