1、单链表
acwing 826
由于创建结点时new是动态分配空间,超级慢所以笔试的时候用数组来模拟链表
数组连接
第0个点,值 e[0] = 5 指针 ne[0] = 1
第1个点,值 e[1] = 3 指针 ne[1] = 2
第2个点,值 e[2] = 2 指针 ne[2] = 3
第3个点,值 e[3] = 4 指针 ne[3] = -1
此时可以插入的idx= 4
在第2个点后面插入一个值为6的点:e[idx] = 6, ne[idx] = ne[2], ne[2] = idx
可以看到不是按数组的下标顺序排的,是在逻辑上有顺序;
e[ ],ne[ ]数组都是Int类型,head也是int类型,存放的是逻辑代号。 第k个插入的点下标是k,
单链表只能看到后面一个,不能看到前面一个点,所以在o(n)时间复杂度内只能在第k个点后面插入,不能在第k个位置插入。
注意
1、在定义函数时避免关键字 eg. delete(×) remove(√)
2、第k个插入的(1,2,3…,下标是k-1(0,1,2…
3、初始化init head时并不能加int ?因为不允许重复定义
#include <iostream>
using namespace std;
const int N = 100010;
int head, e[N], ne[N], idx;
//初始化
void init(){
head = -1;
idx = 0;
}
//插头
void add_to_head(int x){
e[idx] = x;
ne[idx] = head;
head = idx++;
}
//在第k个插入的后面插入X
void add(int k , int x){
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx++;
}
//删除第k个后面
void remove(int k){
ne[k] = ne[ne[k]];//不用考虑内存
}
int main(){
int m, k, x;
char op;
cin>>m;
init();
while(m--){
cin>>op;
if(op == 'H'){
cin>>x;
add_to_head(x);
cout<<"h";
}
else if(op == 'D'){
cin>>k;
if(!k) head = ne[head];
else remove(k-1);
}
else{
cin>>k>>x;
add(k-1,x);
}
}
for(int i = head; i != -1; i = ne[i]) cout<<e[i]<<' ';
return 0;
}
2、双链表
** Time Limit Exceeded **往往是因为循环截止条件
1、双链表可以用两个虚拟头结点,前面单接链表也可以搞一个虚拟头结点,这样直接用k就不用考虑k-1
2、可以看到k的右边一个,也可以看到K左边一个,所以只用写一个insert
3、在输出时循环的截止条件是i !=右结点即1,起始条件是i = 0结点的右边一个(这里不能用Idx作为截止条件,因为最增删之后,不知道idx是否还在,所以直接在链表中看,虚拟左端点0的右边就是起始条件,右端点1是终止条件)
4、由于输入操作有字符也有字符串,所以定义时应该用string,并且都用双引号==“ ”==。
5、小心第k个插入的数(k=1,2,3…)但是下标idx从2开始,所以是k+1
#include <iostream>
using namespace std;
const int N = 100010;
int m;
int e[N], l[N], r[N], idx;
void pout(){
for(int i = r[0]; i != 1; i = r[i]){
cout<<e[i]<<' ';
}
cout<<endl;
}
//在结点k的左边插入x
void insert(int k, int x){
e[idx] = x;
l[idx] = l[k];
r[l[k]] = idx;
r[idx] = k;
l[k] = idx;
idx++;
//pout();
}
//在结点k的右侧插入x,相当于在r[k]的左边插入
//这是双指针的特点,可以找到k左边的数,而单指针就不可以
//删除结点k
void remove(int k ){
l[r[k]] = l[k];
r[l[k]] = r[k];
}
int main(){
cin>>m;
string op;//错因,这里是字符串不止字符
// 0是左端点,1是右端点
//两个虚拟端点
l[1] = 0;
r[0] = 1;
idx = 2;
while(m--){
cin>>op;
int k, x;
if (op == "L"){
cin>>x;
insert(r[0],x);
}
else if(op == "R"){
cin>>x;
insert(1,x);
}
else if(op == "D"){
cin>>k;
remove(k+1);//第一个插入的idx是2
}
else if(op == "IL"){
cin>>k>>x;
insert(k+1, x);
}
else{
cin>>k>>x;
insert(r[k+1],x);
}
}
pout();
return 0;
}