数组模拟链表

主要关注单链表和双链表中都用到了哪些变量和数组,至于它们的实现方式和之前所学的无异

单链表

/**
 * head: 第一个节点的下标
 * idx: 当前节点可用的下标,第一个节点为0
 * -1: 空节点下标
 * e[i]: 下标为i的节点的value
 * ne[i]: 下标为i的节点的下一个节点的数组下标,类似next指针 
 */
#include <iostream>

using namespace std;

const int N = 1e5 + 10;

int m;
int head, idx, e[N], ne[N];

void init()
{
    head = -1; // 此时链表为空,没有节点,所以代表第一个节点下标的head值应该为-1
    idx = 0;
}
void add_to_head(int x)
{
    e[idx] = x;
    ne[idx] = head;
    head = idx ++;
}
void add(int k, int x) // 在数组下标为k的节点之后插入值为x的节点
{
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx ++;
}
void remove(int k) // 删除数组下标为k的节点的后一个节点
{
    ne[k] = ne[ne[k]];
}

双链表

/**
 * 为了减少边界的判断条件,设立了两个存在但不存储值的边界节点,首尾节点下标分别用0和1表示
 * e[i]: 下标为i的节点的value
 * l[i]: 下标为i的节点的左侧节点的下标值
 * r[i]: 下标为i的节点的右侧节点的下标值
 * 0: 头节点,不代表真实节点,仅起标识作用
 * 1: 尾节点,仅起标识作用,不用-1的原因在于我们应该可以通过尾节点索引到最后一个有意义的节点,1可以作为数组下标但-1不行
 * 
 */
#include <iostream>

using namespace std;

const int N = 1e5 + 10;

int idx, e[N], l[N], r[N];

void init()
{
    r[0] = 1;
    l[1] = 0;
    idx = 2;
}
void add_to_left(int x)
{
    e[idx] = x;
    r[idx] = r[0];
    l[idx] = 0;
    l[r[0]] = idx;
    r[0] = idx;
    ++ idx;
}
void add_to_right(int x)
{
    e[idx] = x;
    l[idx] = l[1];
    r[idx] = 1;
    r[l[1]] = idx;
    l[1] = idx;
    ++ idx;
}
void add(int k, int x) // 在下标为k的节点的右侧插入一个节点
{
    e[idx] = x;
    r[idx] = r[k];
    l[idx] = k;
    l[r[k]] = idx;
    r[k] = idx;
    ++ idx;
}
void remove(int k) // 删除下标为k的节点
{
    l[r[k]] = l[k];
    r[l[k]] = r[k];
}
posted @   0x7F  阅读(81)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示