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