当然,这种模拟方法并非仅仅适用于算法竞赛,有兴趣的同学可以去参考一下操作系统中显示链表的应用。
那么如何表示显示链表呢?
假如有下面的链表。
a->b->c->d->e
我们开两个数组e(表示值),ne(表示下标),e[k]表示第k.value,ne[k]表示k.next。
e[1]=a;e[2]=b;e[3]=c;e[4]=d;e[5]=e;
ne[1]=2;ne[2]=3;ne[3]=4;ne[4]=5;ne[5]=-1;
模板:
前序工作
int head,e[N],ne[N],idx;
//head是头节点,指向第一个节点
//e[N]是值数组,en[k]表示第k个节点的值
//en[N]是"位置数组",en[k]表示第k个节点的下一个节点的位置
//idx表示当前开辟到哪个数组空间了
初始化:
void init(){
head = -1;//下一个位置为null
idx = 0;//当前到第0个位置
}
将x插入到头节点
void addAtFirst(int x){
e[idx]=x;
ne[idx]=head;//注意head本身就指向下一个位置。即它是一个“指针”,指的是第一个位置。一定不能ne[head],这样表示第二个位置
head = idx;
idx++;
}
将x插入到下标为k的元素后面
void addAfter(int k,int x){
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx;
idx++;
}
把下标为k后面的元素删除
void remove(int k){
ne[k] = ne[ne[k]];
}
接下来看一下双链表的表示方法。
e[k]表示k.value。r[k]表示k.right。l[k]表示l.left。
前序工作:
int e[N],r[N],l[N],idx;
初始化:
void init(){
r[0] = 1;//0号点右边是1
l[1] = 0;//1号点左边是0
idx = 2; //从2开始
}
将x插入到下标为k的元素右边
void addAtLeft(int k,int x){
e[idx] = x;
r[idx] = r[k];
l[idx] = k;
l[r[k]] = idx;//要在前面,不然找不到k后面的元素了。
r[k] = idx;
}
如果想插入下标为k的元素的左边,只需要addAtLeft(l[k], x);
删除下标为k的元素
void remove(int k){
r[l[k]] = r[k];
l[r[k]] = l[k];
}