算法:链表

单链表

单链表是一种链式存取的数据结构

链表中的数据是以结点来表示的,每个结点存储两个数据,一是该结点本身的值,二是其指向的下一结点的下标

用e[i]表示节点i的值,用ne[i]表示结点i指向的下一结点的坐标

head表示头结点的下标,idx表示当前已经用到了哪个下标,空结点下标为-1

起初head-->空(即head=-1),idx=0,0为用到的第一个下标,依次递增为1,2,3,4......,因而下标是不会重复的

插入操作:如:a-->b,在结点a,b中插入一个结点,idx为当前的结点下标,首先将要插入的值存储到该idx结点中,然后,将该结点指向b,再将a指向idx

删除操作:如:a-->b-->c,要删除b,则只需将a指向c即可

初始化 

void init(){
head=-1;
idx=0;
}

将x插到头结点

void add_to_head(int x){
e[idx]=x;
ne[idx]=head;
head=idx;
idx++;
}

将x插到下标是k的点后面 

void add(int k,int x){
e[idx]=x;
ne[idx]=ne[k];
ne[k]=idx;
idx++;
}

 将下标是k的点后面的点删掉(注意,这样是删除不了头结点的,删除头结点为head=ne[head])

void remove(int k){
ne[k]=ne[ne[k]];
}

例:

该题是在第k个插入的数后面操作,因为第一个插入的数下标为0,第二个插入的数下标为1,以此类推,因而第k个插入的数下标为k-1

#include<iostream>
using namespace std;
const int N=100010;
int head,idx,e[N],ne[N];
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){
e[idx]=x;
ne[idx]=ne[k];
ne[k]=idx;
idx++;
}
void remove(int k){
ne[k]=ne[ne[k]];
}
int main()
{
int k,x;
char op;
int m;
cin>>m;
init();
while(m--){
cin>>op;
if(op=='H'){
cin>>x;
add_to_head(x);
}
else if(op=='D'){
cin>>k;
if(!k) head=ne[head];
remove(k-1);
}
else{
cin>>k>>x;
add(k-1,x);
}
}
for(int i=head;i!=-1;i=ne[i]) cout<<e[i]<<' ';
cout<<endl;
return 0;
}

双链表 

双链表和单链表思想基本一致,理解了单链表之后,就很容易理解双链表了

单链表是单向的,只可以指向一边,而双链表既可以指向左边,又可以指向右边

l[i]表示i结点向左指向的下标,r[i]表示i结点向右指向的下标

可以用下标0代表头结点,用下标1代表尾结点,故idx从2开始,这样做的好处是不用像单链表那样在头结点插入一个数和在下标为k的数后面插入一个数的函数要分开写,只要写一个函数就行了

插入操作:要想在k,b之间插入一个结点,首先记录该值,然后先将该结点指向b(即r[k])和k,再将b(即r[k])指向该结点,k指向该结点,最后不要忘记更新idx值

删除操作:要想删除结点k,只需将a指向b,b指向a(a即为l[k],b即为r[k])

初始化 

void init(){
r[0]=1,l[1]=0;
idx=2;
}

 在下标是k的点的右边插入一个点(要想在下标是k的左边插入一个点,只需调用函数add(l[k],x);)

void add(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];
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值