目录
1.前言
2.思路
3.代码实现
4.结语
1.前言
本篇介绍的是用数组模拟双链表,实质上也是以空间换时间的一种手段,数组实现的双链表本质上是静态链表,但是具有实现简单,速度极快等特点。
2.思路
双链表需要存储3种数据:值,左结点地址,右结点地址。我们创建3个数组分别将这些值存入!
头结点以及尾结点,我们可以用数组的0,1号元素进行存储。
传统双链表的地址可以等价为数组双链表中的数组下标。
我们将要模拟的是这种结构的双链表。
3.代码实现
我们以一道例题来引入该链表的功能实现
题目出处:https://www.acwing.com/problem/content/829/
解题之前,下标作为结点地址的思想一定要把握住,而且除了a[N]外,其他所有的值都与下标有关!
#include
using namespace std;
const int N = 100010;
//l[N]存储某结点的左结点的下标
//r[N]存储某结点的右结点的下标
//a[N]存储某结点存储的值
int a[N],l[N],r[N];
//idx表示某结点的下标(用到了第几个结点)
int idx=0;
//删除操作,将第k个数删除
void dele(int k)
{
r[l[k]]=r[k];
l[r[k]]=l[k];
}
//插入操作,在第k个插入的结点的后面插入新的结点,并赋值x
void insert(int k,int x)
{
//下标为idx,赋值x
a[idx]=x;
//下标为idx的结点,右边存储第k个插入的结点右连接结点的下标
r[idx]=r[k];
//下标为idx的结点,左边存储第k个插入的结点的下标k
l[idx]=k;
//第k个插入的结点的右结点的左侧连接的结点改为下标为idx的结点
l[r[k]]=idx;
//第k个插入的结点的右侧连接的结点改为下标为idx的结点
r[k]=idx;
//已经创建好新结点,结点下标加1
idx++;
}
//初始化双链表,插入头结点与尾结点(此时结点数为2)
void init()
{
l[0] = -1;
r[0] = 1;
l[1] = 0;
r[1] = -1;
idx = 2;
}
int main()
{
//初始化
init();
int M;
cin>>M;
while(M--)
{
string op;
cin>>op;
int k,x;
if(op=="R")
{
//因为下标为1的结点是尾结点,l[1]表示尾结点的左侧第一个结点的下标
cin>>x;
insert(l[1],x);
}
else if(op=="D")
{
//下标为0是第1个插入的结点,下标为1是第2个插入的结点,第k个插入的结点的下标为k+1
cin>>k;
dele(k+1);
}
else if(op=="L")
{
cin>>x;
insert(0,x);
}
else if(op=="IL")
{
//下标为0是第1个插入的结点,下标为1是第2个插入的结点,第k个插入的结点的下标为k+1
cin>>k>>x;
insert(l[k+1],x);
}
else if(op=="IR")
{
//下标为0是第1个插入的结点,下标为1是第2个插入的结点,第k个插入的结点的下标为k+1
cin>>k>>x;
insert(k+1,x);
}
}
//打印链表
for(int i = r[0];i!=1;i=r[i])
{
cout<
可以跟着例题来画图,再看代码也许会更快的理解这个思路!
4.结语
本篇作为算法模板使用,以后会继续更新栈与队列的数组实现。