数组模拟链表

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

单链表

/**
 * 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 @ 2021-01-19 11:16  0x7F  阅读(79)  评论(0编辑  收藏  举报