回顾以及计划:
用了一个多月的时间看完了acwing的第一章基础算法,并完成了相关笔记,接下来的系列是对第二章数据结构的笔记以及相关习题。我觉得学习速度有点慢了,争取在这一学期能把所有的课程完成,并着手一些java项目的实战。主要是学校这学期开了三门大课:编译原理,操作系统、计算机网络,老师讲的不咋的却总要阶段考试,害。
826. 单链表
输入样例:
10
H 9
I 1 1
D 1
D 0
H 6
I 3 6
I 4 5
I 4 5
I 3 4
D 6
输出样例:
6 4 6 5
# include <iostream>
using namespace std;
const int N = 100010;
int e[N],ne[N],head,idx;
void init()
{
//head初始化为空节点
head=-1;
ne[idx]=0;
}
//头插节点x
void add_to_head(int x)
{
e[idx]=x;
ne[idx]=head;
head=idx++; //head更新为第一个插入的节点
}
//在k-1的后面插入节点x
void insert(int k,int x)
{
e[idx]=x;
ne[idx]=ne[k];
ne[k]=idx++;
}
//删除k-1个节点后面的节点
void remove(int k)
{
ne[k]=ne[ne[k]];
}
int main()
{
int n;
cin>>n;
init();
while(n--)
{
char op;
int k,x;
cin>>op;
if(op=='H')
{
cin>>x;
add_to_head(x);
}
else if(op=='I')
{
cin>>k>>x;
insert(k-1,x);
}
else
{
//k=0时删除头节点
cin>>k;
if (!k) head=ne[head];
remove(k-1);
}
}
for(int i=head;i!=-1;i=ne[i]) printf("%d ",e[i]);
return 0;
}
易错点:
- D 0 表示删除头节点,head=ne[head]=-1;
- 忘记初始化
- op用char定义
827. 双链表
输入样例:
10
R 7
D 1
L 3
IL 2 10
D 3
IL 2 7
L 8
R 9
IL 4 7
IR 2 2
输出样例:
8 7 7 3 2 9
题解参考自:https://www.acwing.com/solution/content/5052/
这里需要注意的是:头尾用了下标0和1,这是为了方便在头的右侧,尾的左侧插入数。在链表的最左端插入x = 在0的右面插入x;在链表的最左端插入x = 在1的左面插入x。所以新插入的第一个数下标从2开始,第k个插入的数下标为k+1。
# include <iostream>
using namespace std;
const int N = 100010;
int e[N],l[N],r[N],idx;
//初始化
void init()
{
r[0]=1;
l[1]=0;
idx=2;
}
//在k的右边插入x
void insert(int k,int x)
{
e[idx]=x;
r[idx]=r[k],l[idx]=k;
l[r[k]]=idx,r[k]=idx;
idx++;
}
//删除k节点
void remove(int k)
{
r[l[k]]=r[k];
l[r[k]]=l[k];
}
int main()
{
int n;
cin>>n;
init();
while(n--)
{
int k,x;
string op;
cin>>op;
if(op=="L")//在链表的最左端插入x
{
cin>>x;
insert(0,x);
}
else if(op=="R")//在链表的最左端插入x
{
cin>>x;
insert(l[1],x);
}
else if(op=="IL")//在k-1的左侧插入x
{
cin>>k>>x;
insert(l[k+1],x);
}
else if(op=="IR")//在k-1的右侧插入x
{
cin>>k>>x;
insert(k+1,x);
}
else //删除下标为k+1的数
{//因为头尾用了0、1,所以数从2开始,第k个插入的数下标为k+1
cin>>k;
remove(k+1);
}
}
for(int i=r[0];i!=1;i=r[i]) printf("%d ",e[i]);
}
易错点:
- 忘记init()
- 忘记else if的else
- 忘记写成k+1
- IR、IL的意义弄混