用数组模拟链表,因为结构体方式实现非常慢,做题时用数组更方便操作且快
单链表
#include<iostream>
using namespace std;
const int N = 100010;
int head, idx, e[N], ne[N];//e[N]存data,ne[N]存指针指向的结点下标
//初始化
void init()
{
head = -1;//头结点下标
idx = 0;//一个指针,指向存储当前使用的结点
}
//将x插入到头结点
void add_head(int x)
{
//e[N]存data,ne[N]存指针指向的结点下标
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的点后面的点删掉
void remove(int k)
{
ne[k] = ne[ne[k]];//直接指向被删除点后面的点
}
int main()
{
ios::sync_with_stdio(false);
int m;
cin >> m;
init();
while(m -- )
{
int k, x;
char op;
cin >> op;
if(op == 'H')
{
cin >> x;
add_head(x);
}
else if(op == 'D')
{
cin >> k;
if(! k) head = ne[head];//删除头结点
remove(k - 1);
}
else//插入k后
{
cin >> k >> x;
add(k - 1, x);
}
}
for(int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';
cout << endl;
}
双链表
双链表也可以用数组来模拟,需要增加左、右两个数组存放指向左右结点的指针
#include <iostream>
#include <string>
using namespace std;
const int N = 100010;
int m;
int e[N], l[N], r[N], idx;
// e[]表示节点的值,l[]表示节点的左指针,r[]表示节点的右指针,idx表示当前用到了哪个节点
//初始化
void init()
{
//0表示左端点 ,l是右端点
r[0] = 1, l[1] = 0;//head->next = tail,tail->next = head
idx = 2;//加上两个结点
}
//在下标是k的点的右边插入x,不论左边右边,都可以表示为右插
void add(int k, int x)//insert
{
e[idx] = x;
r[idx] = r[k];
l[idx] = k;
l[r[k]] = idx;//newNode->next->pre = newNode
r[k] = idx;
idx ++ ;
}
//删除结点a
void remove(int k)
{
r[l[k]] = r[k];//k->pre->next = k->next
l[r[k]] = l[k];//k->next->pre = k->pre
}
int main()
{
ios::sync_with_stdio(false);
int m;
cin >> m;
init();
while(m -- )
{
int k, x;
string op;
cin >> op;
if(op == "L")
{
cin >> x;
add(0, x);
}
else if(op == "R")
{
cin >> x;
add(l[1], x);
}
else if(op == "D")
{
cin >> k;
remove(k + 1);
}
else if(op == "IL")
{
cin >> k >> x;
add(l[k + 1], x);
}
else
{
cin >> k >> x;
add(k + 1, x);
}
}
for(int i = r[0]; i != 1; i = r[i]) cout << e[i] << ' ';
cout << endl;
return 0;
}
注:第k个插入到点的下标为k - 1.