单链表
https://www.acwing.com
最近学到了一个新的表示链表的方法,用数组模拟表示单链表,开辟两个数组,一个用来存储数据,另外一个用来存储指针的值,此方法比结构体表示单链表的优点在于快速。下面我们用图形表示这种方法,首先需要开辟两个数组e[ ],ne[ ],来存储我们的数据和指针:
从图中我们可以看到需要有 -1来表示数数组指针的结束。另外需要有一个idx来表示我们的下一个将要增加的数组。
首先是创建一个单链表:
//初始化
void init()
{
head = -1;
idx = 0;
}
//头插法
void head_insert(int x)
{
e[idx] = x;//把要插入的值赋给e[]数组
ne[idx] = head; //ne[idx]表示要插入的数的指针指向原来head指向的位置,在这里可以理解为-1;
head = idx;//把原来的头指针指向要插入的值的下标
idx++;//下一个要插入的值依次往后
}
//插在下标为k的后面
void insert(int k, int x)
{
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx;
idx++;
}
//删除第k个位置的数
void remove(int k)
{
ne[k] = ne[ne[k]];//让k的前指针指向下面的后一个指针,相当于略过k的位置
//删除头结点,但是保证头结点存在
void remove_head()
{
head = ne[head];
}
单链表的题目链接:
https://www.acwing.com/problem/content/828/
双链表
双链表和单链表相比多了一个指针,即我们把原来的ne[ ]更改为两个数组,l[ ] 和 r[ ],一个存左指针,一个存右指针。原来保存数据的 e[ ] 数组不变。
//初始化
void init()
{
//0表示左端点,1表示右端点
//0表示head,1表示tail
r[0] = 1,l[1] = 0;
idx = 2;
}
//在下标是K的点的右边,插入数X;
void insert(int k , int x)
{
e[idx] = x;
r[idx] = r[k];
l[idx] = k;
l[r[k]] = idx;//先调用l[r[k]],再修改r[k]
r[k] = idx;
idx++;
}
//删除第k个点
void remove(int k)
{
r[l[k]] = r[k];
l[r[k]] = l[k];
}