#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int idx,be[N],ne[N],e[N];
int m,a,b;
string c;
void init (){
be[1] = 0;
ne[0] = 1;
idx = 2;
}
void ins_l(int x){
e[idx] = x;
ne[idx] = ne[0];
be[ne[0]] = idx;
ne[0] = idx;
be[idx] = 0;//注意顺序
idx++;
}
void ins_r(int x){
e[idx] = x;
ne[be[1]] = idx;
be[1] = idx;
ne[idx] = 1;
be[idx] = be[1];
idx++;
}
void remove(int k){
be[ne[k]] = be[k];
ne[be[k]] = ne[k];
}
void ir(int k,int x){
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx;
be[ne[k]] = idx;
be[idx] = k;
idx++;
}
void il(int k,int x){
e[idx] = x;
ne[be[k]] = idx;
be[idx] = be[k];
be[k] = idx;
ne[idx] = k;
idx++;
}
int main(){
init();
cin >> m;
while(m--){
cin >> c;
cout << c << endl;
if(c == "R"){
cin >> a;
ins_r(a);
}else if(c == "L"){
cin >> a;
ins_l(a);
}else if(c == "D"){
cin >> a;
remove(a + 1);
}else if(c == "IR"){
cin >> a >> b;
ir(a + 1,b);
}else{
cin >> a >> b;
il(a + 1,b);
}
for(int i = ne[0];i != 1;i = ne[i]) cout << e[i] << ' ';
cout << endl;
}
for(int i = ne[0];i != 1;i = ne[i]) cout << e[i] << ' ';
return 0;
}
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
在双链表中删除一个节点时,需要注意以下几个问题:
ne
指针应该指向要删除节点的后继节点。be
指针应该指向要删除节点的前驱节点。be
和 ne
指针应该指向 0
,以便释放该节点的内存。在您的代码中,删除节点的函数 remove
只实现了前两个步骤,但没有将要删除节点的 be
和 ne
指针指向 0
,因此可能会导致删除节点后访问到已经被释放的内存。
为了解决这个问题,您可以修改 remove
函数,将要删除节点的 be
和 ne
指针都指向 0
。具体来说,可以将 remove
函数修改为如下代码:
void remove(int k){
be[ne[k]] = be[k];
ne[be[k]] = ne[k];
be[k] = ne[k] = 0;
}
这样,在删除节点后,该节点的 be
和 ne
指针会被设置为 0
,以便释放该节点的内存。
另外,您在主函数中调用 remove
函数时,传入的参数是 a + 1
,而不是 a
。这是因为您的链表中第一个节点是虚拟头节点,而非实际存储数据的节点。因此,当您要删除第 k
个节点时,实际需要删除的是第 k+1
个节点。
综上所述,您可以将主函数中的 remove
函数调用改为 remove(a + 2)
,即可正确删除第 a
个节点。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢