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


    只是先邻接表时,我们使用了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
  • 相关阅读:
    ngrok实现内网穿透window下,vue项目invalid host header报错
    sed命令在Mac和Linux下的不同
    Vue和vue-cli和webpack和nodejs
    Cesium 简介
    构建LangChain应用程序的示例代码:31、连接大型语言模型与机器学习社区的系统-HuggingGPT教程
    arduino 记录
    查看自己创建的用户及子用户创建的用户
    Vue官方文档(48): vuex的基本使用
    带你了解MySQL数据库(三)
    Golang 开发实战day04 - Standard Library
  • 原文地址:https://blog.csdn.net/AliceK1008/article/details/125413104