- 826. 单链表
- 827. 双链表
回顾以及计划:
用了一个多月的时间看完了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
# includeusing 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定义
输入样例:
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。
# includeusing 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的意义弄混



