一、单链表
模板:
//head:表示头结点的下标
//e[N]:表示表示结点i的值
//ne[N]:表示结点i的next指针是多少
//idx表示当前已经用到了哪个点
int head, e[N], ne[N], idx;
//初始化
void init()
{
head = -1;
idx = 0;
}
// 在链表头插入一个数x
void insert_to_head(int x)
{
e[idx] = x;
ne[idx] = head;
head = idx;
idx ++;
}
//在第k个节点后插入x
void insert(int x, int k)
{
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx;
idx ++;
}
//把第k个点的后一个结点删除
void remove(int k)
{
ne[k] = ne[ne[k]];
//删除头结点(第一个结点)-->保证头结点存在
//head = ne[head]
}
二、双链表
模板:
// e[]表示节点的值
//l[]表示节点的左指针
//r[]表示节点的右指针
//idx表示当前用到了哪个节点
int e[N], l[N], r[N], idx;
// 初始化
void init()
{
//0是左端点,1是右端点
r[0] = 1, l[1] = 0;
idx = 2;
}
// 在节点k的右边插入一个数x
void insert(int a, int x)
{
e[idx] = x;
l[idx] = k, r[idx] = r[k];
l[r[k]] = idx, r[k] = idx ++ ;
}
// 删除节点k
void remove(int k)
{
l[r[k]] = l[k];
r[l[k]] = r[k];
}
- 在 remove(int k+1) 要用 k+1 的原因是 双链表的起始点是2。 所以,每个插入位置k的真实位置应该为 k-1+2 = k+1 (在单链表中为 k-1)。
- 0, 1 节点的作用是边界。0为左边界,1为右边界。他俩在这里有点类似保留字的作用。正因如此,我们的idx也是从2开始
- 最后遍历输出结果的 for (int i = rn[0]; i != 1; i = rn[i])。从 rn[0] 开始是因为 0 为左边界,而终止条件 i==1是因为1为右边界(如果碰到,说明已经遍历完毕