• 邻接表的链表实现——链式前向星


    只是先邻接表时,我们使用了vector来存储每个顶点连出的边。但是由于vector的常数很大,对于某些时间限制较为严格的情况,使用vector存储邻接表会导致程序超时。因此,我们需要一种更高效的存储方式——链式前向星

    链表是什么

    链表一般会有一个结构体表示一个节点,然后节点之间首尾相接的结构就叫链表。

    struct node {
        int val;
        node *nxt;
    };
    
    • 1
    • 2
    • 3
    • 4

    这种只包含下一个元素,对于查找上一个元素需要将整个链表再遍历一遍,为了使用方便,也有双向或者循环链表的说法,就可以不单找到它的下一个节点,也可以找到它前一个节点。

    struct node {
        int val;
        node *nxt, *pre;
    };
    
    • 1
    • 2
    • 3
    • 4

    基于链表的邻接表实现

    v表示这条边的终点
    next表示这条边的起点的下一条边的编号
    p[u]表示以u为起点的第一条边的编号

    第一步

    定义结构体存储图

    struct edge{
        int v,next;
    }e[M];
    
    • 1
    • 2
    • 3

    第二步

    初始化,将以所有点为起点的边的第一条边编号设为-1

    memset(p,-1,sizeof(p));
    
    • 1

    第三步

    存图(将当前这条边插入到最前面)
    u表示这条边的起点,v表示这条边的终点,eid表示这条边的编号
    首先,存储这条边的终点v
    然后,存储这条边的下一条边为当前的p[u](曾经第一条边的编号,现在第二条变得编号)
    其次,将p[u]更新为这条边的编号
    最后,将eid++,因为边的编号是从0~m-1排列的,输入的第k次的编号就是k

    void insert(int u,int v){
        e[eid].v=v;
        e[eid].next=p[u];
        p[u]=eid++;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    第四步

    读入输入信息,每条边都建立为双向边

    for (int i = 0; i < m; i++) {
            int u, v;
            cin >> u >> v;
            insert(u, v);
            insert(v, u);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    第五步

    从起点分别是1~n,j从当前起点的第一条边开始枚举,每次枚举当前边的下一条边,当这条边的编号为-1时停止枚举

    for(int i=1;i<=n;i++){
            for(int j=p[i];j!=-1;j=e[j].next){
            }
    }
    
    • 1
    • 2
    • 3
    • 4

    链式前向星写法总结

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int M = 1000000;
    const int N = 10000;
    struct edge{
        int v,next;
    }e[M];
    int p[N],eid;
    void insert(int u,int v){
        e[eid].v=v;
        e[eid].next=p[u];
        p[u]=eid++;
    }
    int main() {
        int n, m;
        cin >> n >> m;
        memset(p,-1,sizeof(p));
        for (int i = 0; i < m; i++) {
            int u, v;
            cin >> u >> v;
            insert(u, v);
            insert(v, u);
        }
        for(int i=1;i<=n;i++){
            for(int j=p[i];j!=-1;j=e[j].next){
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    java计算机毕业设计家庭理财管理系统源码+数据库+lw文档+系统
    【动态规划】按位与最大的最长子数组
    C++Qt开发——动画框架、状态机框架
    2、MQ高级
    从内核世界透视 mmap 内存映射的本质(原理篇)
    C++参考好资源网址推荐
    MySQL——动态SQL拼接
    FlyWeight(享元模式)
    umich cv-6-1 循环神经网络基本知识
    数据结构入门-13-图
  • 原文地址:https://blog.csdn.net/AliceK1008/article/details/125413104