单链表
自己用vector写了一个单链表(超时)
#include<iostream>
#include<vector>
template class std::vector<int>;
using namespace std;
const int N=1e5+10;
int M;
char s;int k,x;
vector <int> v;
int record[N];//设置一个数组用于记录第k个被插入的数字所在的位置
int num=0;
void fresh(int l){
//更新整个记录数组,l为更新的起始序号
for(int i=1;i<num;i++){//注意这里是<num,因为num位置上不需要搞
if(record[i]>=l){
record[i]++;//后移一位
}
}
}
void fresh_delete(int l){
//更新整个记录数组,l为更新的起始序号
for(int i=1;i<=num;i++){//注意这里是<num,因为num位置上不需要搞
if(record[i]>=l){
record[i]--;//前移一位
}
}
}
int main(){
cin>>M;
while(M--){
cin>>s;
if(s=='I'){
cin>>k>>x;
//cout<<v.size()<<endl;
v.insert(v.begin()+record[k]+1,x);
num+=1;
record[num]=record[k]+1;
fresh(record[k]+1);
}
else if(s=='H'){
cin>>x;
v.insert(v.begin(),x);
num+=1;
record[num]=0; //第num个被插入的数字位置应该为0
fresh(0);
}
else{
cin>>k;
if(k==0){
v.erase(v.begin());
fresh_delete(0);
}
else{
v.erase(v.begin()+record[k]+1);
fresh_delete(record[k]+1);
}
}
}
vector <int> ::iterator it=v.begin();
for(it;it!=v.end();it++){
cout<<*it<<" ";
}
return 0;
}
由于本题中的k并不是链表中的第k个数字,而是第k个被插入的数字,因此:
- 我的方法。 单独用数据结构记录链表,然后用record记录第k个被插入的数字当前的位置(需要不断更新位置,时间复杂度大)
- 更好的方法。直接用一个数组把每个被插入的数字放好,然后连接这个数组的元素,如下图所示:(这个数组中元素的相对次序就是被插入的顺序)
用两个数组模拟链表的实现:
定义变量:
- head:头节点的位置
- e[]:数组被插入的顺序
- ne[i]:第i个位置的元素下一个指向的地址
- idx: 记录当前插入了几个元素
实现代码
#include<iostream>
using namespace std;
const int N=1e5+10;
int head;
int e[N],ne[N];
int idx;
void init(){
head=-1;//注意这里的-1!!!
idx=1;
}
// 将x插到头结点
void add_to_head(int x){
e[idx]=x;
ne[idx]=head;
head=idx;
idx++;
}
// 将x插到下标是k的点后面
void add(int k, int x){
e[idx]=x;
ne[idx]=ne[k];
ne[k]=idx;
idx++;
}
// 将下标是k的点后面的点删掉
void remove(int k)
{
ne[k]=ne[ne[k]];
}
int main(){
int m;
cin>>m;
int k,x;
char s;
init();
while(m--){
cin>>s;
if(s=='H'){
cin>>x;
add_to_head(x);
}
else if (s=='D'){
cin>>k;
if(k==0){
head=ne[head];
}
else{
remove(k);
}
}
else{
cin>>k>>x;
add(k,x);
}
}
for(int i=head;i!=-1;i=ne[i])
cout<<e[i]<<" ";
return 0;
}