c++手写链表
这个手写链表主要围绕紫书(刘汝佳著)上破损的键盘的题解进行讲解。
破损的键盘代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
char s[100000+5];
int next[100000+5];
int now=last=0;
int main()
{
while(scanf("%s",s+1)==1)
{
int len=strlen(s+1);
for(int i=1;i<=len;i++)
{
if(s[i]=='[')now=0;
else if(s[i]==']')now=last;
else
{
next[i]=next[now];
next[now]=i;
if(last==now)last=i;
now=i;
}
}
for(int i=next(0);i!=0;i=next(i))
cout<<s[i];
cout<<endl;
}
return 0;
}
(与书中代码略有不同,因为字段代码是我自己写的,所以质量上肯定没有刘老写的好 )
代码核心:
for(int i=1;i<=len;i++)
{
if(s[i]=='[')now=0;
else if(s[i]==']')now=last;
else
{
next[i]=next[now];
next[now]=i;
if(last==now)last=i;
now=i;
}
}
要聊链表首先应该了解链表长什么样:
链表可以分成两部分,一个是数据部分,一个是指向部分。指向部分就是下一个数据应该是什么。
可以与数组进行对比:我么都知道数组的读取时顺序读取,比如说:存在一个数组 1 2 3 4 5
当我们读取完 1 的时候,它下一个读取的一定是 2 。如果把这个数组改写成链表形式的话:
(1,2)(2,3)(3,4)(4,5)(5,?)
那么只用将(1,2)改写为(1,3)那么当计算机读取完 1 后,下一个读取的数应该是 3。所以链表的最大作用就是可以改写顺序,这对数据的插入,删除等有很大作用。
聊回本题,那么如何手写一个代码来模拟链表呢?我认为是数组(答案不唯一),即一个数组用来储存数据,一个用来储存指向地址。
详解一:
next[i]=next[now];
next[now]=i;
if(last==now)last=i;
now=i;
这段代码的图解如下:
中间步骤相同,就跳过
当遇到 [ 的时候。
now变为开头的位置。last不变。
之后继续。
这里我放了一个小错误,没有将now的值修改,因为修图要花很多时间,就口头提示下,图就不修改了,大家注意下。
当遇到 ] 的时候。把now变为last。
继续操作。
如哦弄清楚这个过程是怎么变化的话,代码就自然理解了
还有一个比较有意思的点是用链表的输出:
for(int i=next(0);i!=0;i=next(i))
cout<<s[i];
cout<<endl;
可以学习下。