双链表 - xiongyuqing - 博客园 (cnblogs.com)
每个节点有两个指针,一个指向下一个节点,一个指向前一个节点。在代码实现中使用左节点,右节点描述
初始化
e[N]
:表示节点的值
l[N]
:表示左指针指向的节点
r[N]
:表示右指针指向的节点
idx
:已经使用过的节点编号(当前正在访问的节点编号)
- 0 号点是头节点head
- 1 号点是尾节点tail
int e[N], l[N], r[N], idx;
// 初始化
void init()
{
// 0 表示左端点,1表示右端点
r[0] = 1; l[1] = 0;
idx = 2;
}
将值为 x 的节点插入到节点 k 的右边
- 首先存储值为 x 的新节点
- 将新节点的左指针指向 k 节点,右指针指向节点 k 的右节点(红色的1,2两步)
- 将节点 k 的右节点的左指针指向新的节点(绿色第3步)
- 将节点 k 的右指针指向新节点(绿色第4步)
// 在k节点的右边插入x
void add(int k, int x)
{
e[idx] = x;
l[idx] = k;
r[idx] = r[k];
l[r[k]] = idx;
r[k] = idx++;
}
如果想在 k k k 节点的左边插入值为 x x x 的节点,只需要在
l[k]
的右边插入:add(l[k], x);
删除第 k 个节点
- 节点 k 的左节点的右指针,指向节点 k 的右节点
- 节点 k 的右节点的左指针,指向节点 k 的左节点
// 删除节点k
void remove(int k)
{
r[l[k]] = r[k];
l[r[k]] = l[k];
}
例题
#include <iostream>
#include <string>
using namespace std;
const int N = 1e5 + 5;
int e[N], l[N], r[N], idx;
void init()
{
r[0] = 1;
l[1] = 0;
idx = 2;
}
void add(int k, int x)
{
e[idx] = x;
l[idx] = k;
r[idx] = r[k];
l[r[k]] = idx;
r[k] = idx ++;
}
void remove(int k)
{
r[l[k]] = r[k];
l[r[k]] = l[k];
}
int main()
{
init();
int T, k, x;
cin >> T;
string op;
while(T--)
{
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] << " ";
return 0;
}