AcWing算法基础课-利用数组模拟链表

179 阅读2分钟

利用数组模拟链表,我们又可以称之为静态链表。
在之前我们接触过使用指针进行链表的实现,使用指针虽然可以进行动态的分配内存,来实现对于空间的节省,但是对于算法来说,主要的思路是用空间来交换时间,如果我们可以利用数组来模拟链表,则可以达到这一个效果。

数组模拟单链表

我们定义一个head来表示头节点的下标,如果其值为-1,则表示链表为空
这里主要定义的是e数组和ne数组,这里可以理解为element和nextElement,即e[i]表示第i个节点的值,而ne[i]表示i的next指针是第几个位置。
而我们还定义了一个idx,用来表示当前程序已经用到了哪个点。

/*
 * @Author: IndexYang 
 * @Date: 2021-11-19 10:03:55 
 * @Last Modified by: IndexYang
 * @Last Modified time: 2021-11-19 11:08:03
 */

const int N = 100010;

// head 表示头结点的下标
// e[i] 表示节点i的值
// ne[i] 表示节点i的next指针是多少
// idx 存储当前已经用到了哪个点

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

void init(){
    head = -1;
    idx = 0;
}
void add_to_head(int x){
    e[idx] = x; 
    ne[idx] = head; //将idx的下一个指向head的下一个节点,即头插入
    head = idx ++; //更新head指向的位置
}
void add(int k,int x){
    e[idx] = x;
    ne[idx] = ne[k]; //将idx的下一个位置指向k的下一个位置,即在k后插入
    ne[k] = idx ++; //更新k节点指向的位置
}
void remove(int k){
    ne[k] = ne[ne[k]]; //将k的下一个位置指向k的下一个的下一个
}

数组模拟双链表

利用数组模拟双链表和模拟单链表基本一致,只是双链表模拟需要left和right数组。

/*
 * @Author: IndexYang 
 * @Date: 2021-11-19 11:07:36 
 * @Last Modified by: IndexYang
 * @Last Modified time: 2021-11-19 11:08:56
 */

// e[]表示节点的值
// l[]表示节点的左指针
// r[]表示节点的右指针
// idx表示当前用到了哪个节点

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

//初始化
void init(){
    r[0] = 1;
    l[1] = 0;
    idx = 2;
}
//在a的右边插入一个数x
void insert(int a,int x){
    e[idx] = x;
    l[idx] = a; r[idx] = r[a]; //idx连接左右
    l[r[a]] = idx; r[a] = idx; //a的下一个节点连接idx,然后a的右边连接idx
    idx++;
}
//若在a的左边插入一个数
//insert(l[a],x);

//删除a节点
void remove(int a){
    r[l[a]] = r[a]; //a的左边的右边 = a的右边
    l[r[a]] = l[a]; //a的右边的左边 = a的左边
}