数组模拟链表(链式前向星),存储单链表,树,图

本文是对[数据结构](4)单链表_世真的博客-CSDN博客[C++数据结构](33)图,图的遍历,最小生成树,最短路径算法详解_世真的博客-CSDN博客_c++实现图及最小路径的补充。

链式前向星

链式前向星就是用数组模拟链表。它的特点是代码简洁,避免了 new 的开销,效率高。适合笔试做题时使用(不需要考虑空间利用率和内存泄漏的问题)。

一个用数组模拟的单链表

  • head 表示头结点的编号,初始为 -1 表示空结点

  • e[i] 表示编号为 i 的结点的值

  • nxt[i] 表示编号为 i 的结点的下一个结点的编号

  • idx 用于给结点编号


  • add_front 头插

  • add 在编号为 k 的结点后面插入一个结点

  • remove 删除编号为 k 的结点的后一个结点

const int N = 100010;

int head, e[N], nxt[N], idx;

void init() {
    head = -1;
    idx = -1;
}

void add_front(int x) {
    e[++idx] = x;
    nxt[idx] = head;
    head = idx;
}

void add(int k, int x) {
    e[++idx] = x;
    nxt[idx] = nxt[k];
    nxt[k] = idx;
}

void remove(int k) {
    nxt[k] = nxt[nxt[k]];
}

图的领接表存储本质上也是链表,可以使用链式前向星

const int N = 100010, M = 2 * N;

int n, m;
int h[N], e[M], nxt[M], idx;
int q[N];
bool vis[N];

void init() {
    memset(h, -1, sizeof(h));
    idx = -1;
}

void add(int a, int b) {
    e[++idx] = b;
    nxt[idx] = h[a];
    h[a] = idx;
}

void dfs(int u) {
    vis[u] = true;
    for (int i = h[u]; i != -1; i = nxt[i]) {
        int j = e[i];
        if (!vis[j]) dfs(j);
    }
}

void bfs(int u) {
    q[0] = u;
    int hh = 0, tt = 0;
    vis[u] = true;
    while (hh <= tt) {
        int t = q[hh++];
        for (int i = h[t]; i != -1; i = nxt[i]) {
            int j = e[i];
            if (!vis[j]) q[++tt] = j;
        }
    }
}

对于有向图,插入一条从 ab 的边,则调用 add(a, b);对于无向图,插入一条 ab 之间的边,则调用 add(a, b) add(b, a)

另外,由于树也是图的一种,所以我们也可以使用这种存储方式。使用 C++ 的 vector<vector<int>> 也可以模拟邻接表,并且能够简化 add 函数的写法(因为push_back()函数能够代替我们使用 idx 手动对结点进行编号的过程),但是这些 STL 容器运行速度较慢,做题时谨慎使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世真

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值