https://www.acwing.com/problem/content/829/
与数组模拟单链表相似
但是与之相比多一个l[N],r[N]用这两个向量表示每个结点的前驱和后继
初始状态:
令head为0,tail为1,初始就这两个点,开头和结尾
插入:
删除:
#include<iostream>
using namespace std;
const int N = 100010;
int k;
int m;
int e[N],l[N],r[N],idx,num;
void init()
{
r[0]=1,l[1]=0;//指明head和tail的r与l
idx=2;//0与1被head和tail占用了
}
void add(int k,int x)//下标为k的点右边插入点
//若要在k点左边插入,则add(l[k],x)即是在l[k]的右边插入点
{
//新点
e[idx]=x;//新点赋值
r[idx]=r[k];//新点的r指针指向k点的右指针
l[idx]=k;//新点l指针指向k
//旧两端点
l[r[k]]=idx;//设置右边旧点左指针指向新点
r[k]=idx;//设置左边旧点又指针指向新点
idx++;
}
void remove(int k)//删除第k个点
{
r[l[k]]=r[k];//设置k点的左点的右指针为k点的右点
l[r[k]]=l[k];//设置k点的右点的左指针为k点的左点
}
int main()
{
cin >> m;
init();
while(m--)
{
string cmd;
int x;
cin >> cmd;
if(cmd == "L")
{
cin >> x;
add(0,x);//0表示head,即在head的右端插入点为第一个点
}
else if(cmd == "R")
{
cin >> x;
add(l[1],x);//1表示tail,在tail的左端插入点为最后一个点
}
else if(cmd == "D")
{
cin >> k;
remove(k+1);//第k个点,因为idx从2开始分配,第1个点为2,第2个点为3,那么第k个点为下标为k+1
}
else if(cmd == "IL")
{
cin >> k >> x;
add(l[k+1],x);//与D同理,k+1为第k个点idx下标,在k+1左段的点的右边插入点
}
else
{
cin >> k >> x;
add(k+1,x);//在k的右侧插入点
}
}
for(int i=r[0];i != 1;i=r[i]) cout << e[i] << ' ';
cout << endl;
return 0;
}