在创建单链表时如果使用使用动态的单链表,那么每创建一个结点时就会使用new 当数据比较大的时候,程序运行的时间很长 所以在写题的时候 往往会那数组来模拟一个链表;
先进行如下定义:
head为头结点的头指针;
idx为当前记录到那个结点;
那数组e【N】和ne[N]来模拟一个静态链表,数组e用来储存当前结点的值,ne表示下一个结点的下标;
初始化
初始化时将头节点的头指针指向-1,此时idx=0,因为要下一个处理下标为0的结点
void init()//初始化链表
{
head=-1;
idx=0;
}
插入操作
向头节点后面插入一个数
void push_head(int x)
{
e[idx]=x;
ne[idx]=head;
head=idx;
idx++;
}
向第k个结点后插入一个结点(第k个表示的是第k个插入的数,不是位置上的第k个
void push_k(int k,int x)
{
e[idx]=x;
ne[idx]=ne[k];
ne[k]=idx;
idx++;
}
删除
将第k个结点删除
当k为0时表示删除头节点
void pop_head()
{
head=ne[head];
}
不为0时
void pop_k(int k)
{
ne[k]=ne[ne[k]];
}
例题:
代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int n,ne[N],e[N],idx,head;
void init()
{
head=-1;
idx=0;
}
void push_head(int x)
{
e[idx]=x;
ne[idx]=head;
head=idx++;
}
void push_k(int k,int x)
{
e[idx]=x;
ne[idx]=ne[k];
ne[k]=idx++;
}
void pop_k(int k)
{
ne[k]=ne[ne[k]];
}
int main()
{
cin>>n;
init();
while(n--)
{
char op;
int k,x;
cin>>op;
if(op == 'H')
{
cin>>x;
push_head(x);
}
else
if(op == 'I')
{
cin>>k>>x;
push_k(k-1,x);
}
else
{
cin>>k;
if(k==0)
{
head=ne[head];
}
else
{
pop_k(k-1);
}
}
}
for(int i=head;i!=-1;i=ne[i])
{
cout<<e[i]<<" ";
}
}
双向链表
在上面的单向链表中我们可以看出单项链表在遍历时只能沿这一个方向去遍历,而双向链表可以沿两个方向去遍历 这样 就大大的提高了 链表的效率
在模拟双向练表时 可以先模拟两个临界 分别代表左端点和右端点
先说明以下定义
l[N]和r[N]是当前结点的前一个结点的下标和后一个节点的下标;
idx表示当时用到了那一个结点;
e[N]表示当前结点的值
初始化
在这里面的l【1】和r【0】相当于双链表的右左哨兵
void init()//初始化链表
{
l[1]=0;
r[0]=1;
idx=2;
}
插入(向k结点的右侧插入一个数)
void push_k(int k,int x)
{
e[k]=x;
l[r[k]]=idx;
r[idx]=r[k];
l[idx]=k;
r[k]=idx++;
}
这个代码不仅可以实现向双链表k结点的右侧插入还可以实现双链表的最左侧,最右侧,k结点的左侧
向最左侧:只需要让k=r【0】;
向最右侧:只需要让k=l【1】;
向k结点的左侧:只需要让k=l【k】;
删除操作
删除第k个结点
void pop_k(int k)
{
r[l[k]]=r[k];
l[r[k]]=l[k];
}
例题
代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int l[N],r[N],m,e[N],idx;
void push_rx(int k,int x)
{
e[idx]=x;
l[r[k]]=idx;
r[idx]=r[k];
l[idx]=k;
r[k]=idx++;
}
void pop_k(int k)
{
r[l[k]]=r[k];
l[r[k]]=l[k];
}
int main()
{
cin>>m;
r[0]=1,l[1]=0,idx=2;
while(m--)
{
int x,k;
string op;
cin>>op;
if(op=="L")
{
cin>>x;
push_rx(0,x);
}
if(op=="R")
{
cin>>x;
push_rx(l[1],x);
}
if(op=="D")
{
cin>>k;
pop_k(k+1);
}
if(op=="IL")
{
cin>>k>>x;
push_rx(l[k+1],x);
}
if(op=="IR")
{
cin>>k>>x;
push_rx(k+1,x);
}
}
for(int i=r[0];i!=1;i=r[i])
cout<<e[i]<<" ";
return 0;
}