目录
讲一道比较简单的双向链表基础题。【本人码风比较奇怪,请见谅】
题目
知识点
一道双向链表的基础题。
考察的是在链表中加入元素、删除元素和链表的输出。
代码及解释
开头
#include<bits/stdc++.h>
int n,m,l[100005],r[100005],k,p,x;
//l[i]:i编号的前一个 r[i]:i编号的下一个
int main(){
scanf("%d",&n);
l[0]=r[0]=1;//第一个元素
插入元素
for(int i=2;i<=n;i++){//1算已经存在与链表中了
scanf("%d%d",&k,&p);
if(!p){//左侧插入
l[i]=l[k];//新元素前一个为k
r[l[k]]=i;//k上一个的下一个指向i
r[i]=k;//i的下一个元素是k
l[k]=i;//k的左侧元素为i
}else{//右侧插入
r[i]=r[k];//新元素的右边为上一个元素的右边
l[r[k]]=i;//原来k右边的元素的坐标赋值为i
l[i]=k;//新元素左边为k
r[k]=i;//k的右边为新元素
}
}
本蒟蒻认为,插入/删除的过程就像读绕口令,所以需要好好思考,甚至画图。
注意:一定要注意顺序,否则改变了就找不到对应位置了。
一般是这样插入元素的,在使用时可以根据实际情况更改:
删除元素
scanf("%d",&m);
while(m--){
scanf("%d",&x);
if(l[x]==-1)
continue;//如果已经删了
r[l[x]]=r[x];
l[r[x]]=l[x];
l[x]=r[x]=-1;//标记已经删掉了
}
删除元素也像绕口令哈。
输出
for(int i=r[0];i;i=r[i])//只要存在,找到下一个
printf("%d ",i);
return 0;
}
一种很巧妙的for循环方法输出,不断找到下一个值,直到没有下一个。
你们最爱的完整代码
#include<bits/stdc++.h>
int n,m,l[100005],r[100005],k,p,x;
//l[i]:i编号的前一个 r[i]:i编号的下一个
int main(){
scanf("%d",&n);
l[0]=r[0]=1;//第一个元素
for(int i=2;i<=n;i++){//1算已经存在与链表中了
scanf("%d%d",&k,&p);
if(!p){//左侧插入
l[i]=l[k];//新元素前一个为k
r[l[k]]=i;//k上一个的下一个指向i
r[i]=k;//i的下一个元素是k
l[k]=i;//k的左侧元素为i
}else{//右侧插入
r[i]=r[k];//新元素的右边为上一个元素的右边
l[r[k]]=i;//原来k右边的元素的坐标赋值为i
l[i]=k;//新元素左边为k
r[k]=i;//k的右边为新元素
}
}
scanf("%d",&m);
while(m--){
scanf("%d",&x);
if(l[x]==-1)
continue;//如果已经删了
r[l[x]]=r[x];
l[r[x]]=l[x];
l[x]=r[x]=-1;//标记已经删掉了
}
for(int i=r[0];i;i=r[i])//只要存在,找到下一个
printf("%d ",i);
return 0;
}
总结
关于双向链表的插入、删除,总之就是非常乱,实在不行就画图分析。比赛时,除非有很大把握,否则就拿部分分吧……
读完文章,你脑子是否已经缠在一起了呢?