1.链表
主要思想:使用数组实现链表(而不用结构体,结构体代码更长,后续图论也是基于数组实现),即静态链表。因为动态链表使用new申请空间需要较多的时间,而算法要求的是以较少的时间完成任务。
- 单链表,最主要用单链表写邻接表,用邻接表存储图或者树
- 双链表,优化某些问题
1)单链表
**单链表:**头指针head指向第一个结点,初始为-1。数组e[]存储结点的值,数组ne[]存储对应结点的下一个结点的下标,形成一个链条。本质上是用数组下标来操作对应结点
AcWing 826.单链表
实现思路:
-
设置数组e[]存储结点值,数组ne[]存储对应结点下一个结点的下标
-
设置头指针head指向第一个结点,初始值为-1
-
设置指针idx表示当前操作位置,初始为0即指向数组的第一个位置,单增(实际上idx所指向的位置就是将要操作的数组位置,这个位置还未存入结点,每次存入结点后idx需要后移,但删除结点时不用考虑当前数组位置是否浪费而做出某种处理,算法以速度为主,因此删除结点是idx结点不用前移)
#include <iostream>
using namespace std;
const int N=1e6+10;
int e[N],ne[N];
int head,idx;
//初始化
void init(){
head=-1;
idx=0;
}
//链表头插入结点
void add_to_head(int x){
e[idx]=x;
ne[idx]=head;
head=idx;//根据数组表示链表的性质,随着链表头不断插入结点,第一个结点的位置是后移的,即head后移到idx
idx++;//插入结点后idx指针后移
}
//在下标为k的结点后面插入结点
void add(int k,int x){
e[idx]=x;
ne[idx]=ne[k];
ne[k]=idx;
idx++;
}
//删除下标为k的结点后面的结点
void remove(int k){
if(k==-1) head=ne[head];//即删除头结点
else ne[k]=ne[ne[k]];
}
int main() {
int m;
cin>>m;
init();
while(m--)
{
char s;
cin>>s;
if(s=='D')
{
int k;
cin>>k;
remove(k-1);
}
else if(s=='H')
{
int x;
cin>>x;
add_to_head(x);
}
else
{
int k,x;
cin>>k>>x;
add(k-1,x);
}
}
for(int i=head;i!=-1;i=ne[i]) cout<<e[i]<<' ';
return 0;
}
2)双链表
**双链表:**此时没有头指针,固定数组前两个位置的存储,下标0的位置存储链表第一个结点(即左端点),数组下标1的位置存储链表的末尾结点(即右端点)。三个数组,数组e[]存储结点值,数组l[]指向当前结点的左结点(即前驱),数组r[]指向当前结点的右结点(即后继),idx指向当前操作位置.
AcWing 827.双链表
实现思路:类似单链表
- 注意idx初始为2,因为数组前两个位置已固定存储链表首尾结点
- 初始左端点右指向右端点,右端点左指向左端点
#include <iostream>
using namespace std;
const int N=1e6+10;
int e[N],l[N],r[N];
int idx;
int n;
//初始化
void init(){
r[0]=1;
l[1]=0;
idx=2;
}
//在下标为k的结点的右侧插入结点 若是左侧插入结点则传入的k为l[k]
void add(int k,inx){
e[idx]=x;
l[idx]=k;
r[idx]=r[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()
{
cin>>n;
init();
while(n--)
{
string op;
cin>>op;
if(op=="L")
{
int x;
cin>>x;
add(0,x);
}
else if(op=="R")
{
int x;
cin>>x;
add(l[1],x);
}
else if(op=="D")
{
int k;
cin>>k;
remove(k+1);
}
else if(op=="IL")
{
int k,x;
cin>>k>>x;
add(l[k+1],x);
}
else
{
int k,x;
cin>>k>>x;
add(k+1,x);
}
}
for(int i=r[0];i!=1;i=r[i]) cout<<e[i]<<" ";
}