(数据结构)有向图的十字链表(Orthogonal List)表示

十字链表是一种结合了邻接表和逆邻接表的有向图存储方式,它通过为每个顶点添加两个链表分别记录出度和入度,从而方便地同时获取节点的出边和入边信息。本文介绍了十字链表的结构、优点以及C++实现,并展示了如何建立和打印十字链表表示的有向图。
摘要由CSDN通过智能技术生成

十字链表(Orthogonal List)是有向图的另一种链式存储结构,可以看成是将有向图的邻接表和逆邻接表相结合起来得到的一种链表。

就是在邻接表每个头节点加上入度链表

分析有向图的邻接表表示法存在的问题:

虽然邻接表表示可以方便计算某个节点的出度,但不方便计算它的入度 可以方便找到所有从该某个点出发的边,但不方便找到所有指向某个顶点的边

为了解决这样的问题,对邻接表做一些改进,对每一个顶点,增加了一条链表,用于存储指向该顶点的所有边

所以每个顶点都对应着2个链表,一个链表记录所有从该顶点出发的边,另一个链表记录所有指向该顶点的边。

代码实现(c++):

#include<iostream>
using namespace std;
​
typedef long long ll;
const int maxn = 1024;   //最大顶点数
const int maxm = maxn * (maxn - 1);   //最大边数 
int n, m;  //顶点个数,边的个数,顶点的编号从1-n
​
struct Edge{
    int fromValue, toValue;
    Edge* fnext;
    Edge* tnext;
};
struct VNode {
    Edge* inLinkFirst;
    Edge* outLinkFist;
}Vlink[maxn];
​
/*
* 十字链表建边
*
*/
void Link(int from, int to) {
    //建边
    Edge* p = new Edge();
    
    //赋值
    p->fromValue = from;
    p->toValue = to;
    //头插法插入入度头节点
    p->fnext = Vlink[from].outLinkFist;//f表示出
    Vlink[from].outLinkFist = p;
    //头插法插入出度头节点
    p->tnext = Vlink[to].inLinkFirst;
    Vlink[to].inLinkFirst = p;
}
​
/*
打印这个十字链表
*/
void print() {
    for (int i = 1; i <= n; ++i) {
        cout << "V" << i << ":" << endl;
        //以顶点i为尾(指向顶点i)的边
        cout << "in:  ";
        Edge* e = Vlink[i].inLinkFirst;
        while (e) {
            cout << e->fromValue << " -> ";
            e = e->tnext;
        }
        cout << "^" << endl;
        //以顶点i为头(从顶点i出发)的边
        cout << "out: ";
        e = Vlink[i].outLinkFist;
        while (e) {
            cout << e->toValue << " -> ";
            e = e->fnext;
        }
        cout << "^" << endl;
​
    }
}
​
int main() {
​
    //测试
    n = 4;
    m = 7;
    //初始化vlist
    for (int i = 1; i <= n; ++i) {
        Vlink[i].inLinkFirst = NULL;
        Vlink[i].outLinkFist = NULL;
    }
    //以下m行建图
    Link(1, 2);
    Link(1, 3);
    Link(3, 4);
    Link(3, 1);
    Link(4, 1);
    Link(4, 2);
    Link(4, 3);
    print();
    
    return 0;
}

运行结果

在这里插入图片描述
表示的有向图如图所示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值