直接贴代码
const int N=100010;
int e[N]; // 存储插入节点的值
int l[N]; // 指向当前节点的前一个节点
int r[N]; // 指向当前节点的右节点
int idx; // 给每个插入的结点编号
void init(){ // 这是左右边界 0代表左边界,1代表有边界,相当于在 0------1 之间插入结点
r[0]=1; // 形成闭环, 0的下一个节点是1,1的上一个节点是0
l[1]=0;
idx=2; // 因为已经初始化了两个点,这里idx=2(指下一个插入结点的编号)
}
void add(int k,int x){ // 在第k个节点后,添加x
e[idx]=x; // Node*temp=new Node(x);
r[idx]=r[k]; // temp->next=k->next; (k表结点)
l[idx]=k; // temp->prior=k;
l[r[k]]=idx; // k->next->prior=temp;
r[k]=idx; // k->prior=temp; 这个放最后即可,其余的随意
idx++;
}
void remove(int k){ // 移除第k个节点
l[r[k]]=l[k]; // k->next->prior=k->prior;
r[l[k]]=r[k]; // k->prior->next=k->next;
}
问题
-
l[0],l[1],r[0],r[1]
各表示什么?
l[0]
表示左边界的左节点(显然不存在)
l[1]
表示左边界的右节点,就是第一个节点
r[0]
表示右边界的左节点,就是最后一个节点
r[1]
表示右边界的右节点(显然不存在) -
r[0]=1,l[1]=0
有什么作用
r[0]=1
表示第一个节点指向1(有边界)
l[1]=0
表示最后一个节点指向0(左边界); -
idx
为什么初始化为2?
因为0,1
都被左右边界占了,插入节点从下标为2插入 -
如何实现在最左侧插入一个数?
最左侧就是在 左边界 的右侧,即r[0]
,但是我们实现的函数是在k的后边插入,因此这里调用add(0,x)即可 - 如何实现在最右侧插入一个数?
最右侧就是在 右边界 的左侧,即l[1]
,因此直接调用add(l[1],x)
即可 - 为什么右插操作需要
add(k+1,x);
?(+1)
因为开始已经占了0,1
两个节点,因此整体插入的需要右移一个单位(删除操作类似) - 如何实现左插操作?
第k
节点左边插入,相当于在l[k]
节点右边插入,调用add(l[k+1],x)
即可