单链表原理:用e表示改编号的数据,ne表示改编号指向下一个结点的编号

//单链表笔记&16168竞赛团队训练
#include <bits/stdc++.h>

using namespace std;
int head,e[1234567],ne[1234567],idx;//节点数据、指针(下一个编号,不是下标)下一个加入节点的编号
void init(){//初始化
	head=-1;
	idx=0;
}
void add_to_head(int x){//从头插入元素
	e[idx]=x;
	ne[idx]=head;
	head=idx;
	idx++;
}
void add(int k,int x){//从编号为k的结点后面插入元素
	e[idx]=x;
	ne[idx]=ne[k];
	ne[k]=idx;
	idx++;
}
void Delete(int k){//从编号为k的结点后面删除元素
	ne[k]=ne[ne[k]];
}
int main(){
	int n,x,y;
	cin>>n;
	char op;
	init();
	while(n--){
		cin>>op;
		if(op=='H')cin>>x, add_to_head(x);
		else if(op=='D'){
			cin>>x;
			if(x)Delete(x-1);
			else head=ne[head];//从头删
		}else{
			cin>>x>>y;
			add(x-1,y);
		}
	}
	
	for(int i=head;i!=-1/*相当于i~即i取反,i为-1时不成立*/;i=ne[i]){
		cout<<e[i]<<' ';
	}
	return 0;
}

双链表原理:用e表示该编号的数据,l上一个编号,r下一个编号

//双链表笔记
#include <bits/stdc++.h>

using namespace std;
int head,e[1234567],l[1234567],r[1234567],idx;//节点数据、左右指针(下一个编号,不是下标)下一个加入节点的编号
void init(){//初始化
	l[1]=0;
	r[0]=1;
	idx=2;
}
void add(int k,int x){//从头插入元素
	e[idx]=x;
	r[idx]=r[k];
	l[idx]=k;
	l[r[k]]=idx;
	r[k]=idx;
	idx++;
}
void Delete(int k){//删除从左到右第k个元素
	r[l[k]]=r[k];
	l[r[k]]=l[k];
}
int main(){
	int n,k,value;
	string op;
	cin>>n;
	init();
	while(n--){
		cin>>op;
		if(op=="L"){
			cin>>value;
			add(0,value);
		}else if(op=="R"){
			cin>>value;
			add(l[1],value);
		}else if(op=="D"){
			cin>>k;
			Delete(k+1);
		}else if(op=="IL"){
			cin>>k>>value;
			add(l[k+1],value);
		}else{
			cin>>k>>value;
			add(k+1,value);
		}
	}
	
	for(int i=r[0];i!=1;i=r[i]){
		cout<<e[i]<<' ';
	}
	
	
	
	return 0;
}

注意事项:1、输入时要特殊判断,比如head就没有删除功能;

2、e是编号,不是下标!编号按照顺序增加。