一.单链表
void init()//初始化
{
head = -1;
//最开始的时候,链表的头节点要指向-1,
//为的就是在后面进行不断操作后仍然可以知道链表是在什么时候结束
/*
插句题外话,我个人认为head其实就是一个指针,是一个特殊的指针罢了。
刚开始的时候它负责指向空结点,在链表里有元素的时候,它变成了一个指向第一个元素的指针
当它在初始化的时候指向-1,来表示链表里没有内容。
*/
idx = 0;//idx在我看来扮演两个角色,第一个是在一开始的时候,作为链表的下标,让我们好找
//第二在链表进行各种插入,删除等操作的时候,作为一个临时的辅助性的所要操作的元素的下
//标来帮助操作。并且是在每一次插入操作的时候,给插入元素一个下标,给他一个窝,感动!
/*
再次插句话,虽然我们在进行各种操作的时候,元素所在的下标看上去很乱,但是当我们访问的
时候,是靠着指针,也就是靠ne[]来访问的,这样下标乱,也就我们要做的事不相关了。
另外,我们遍历链表的时候也是这样,靠的是ne[]
*/
}
void add_to_head(int x)
{
e[idx] = x;
en[idx] = head;
head = idx;//head现在表示指向第一个元素了,它不在是空指针了。(不指向空气了
idx++;
}
void add(int x, int k)
{
e[idx] = x;
en[idx] = en[k];
en[k] = idx;
idx++;
}
void removes(int k)//将k后面那个点删掉(跳过
{
en[k] = en[en[k]];
}
注1.
此处第二个scanf那里若不加\n,scanf就会被跳过
2.删除头结点的特殊性
二.双链表
void init()//初始化
{
l[1] = 0;
r[0] = 1;
idx = 2;
}
void add(int k, int x)
{
e[idx] = x;
r[idx] = r[k];
l[idx] = k;
l[r[k]] = idx;
r[k] = idx;
idx++;
}
void removes(int k)//将k删掉(跳过
{
l[r[k]] = l[k];
r[l[k]] = r[k];
}
简化小技巧。把head初始化为 0,tail初始化为 N - 1,idx初始化为 1,第 k 个插入的数的下标就是 k。
bug!!!
c++代码是从右向左进行的,因此++操作要谨慎进行