1、单链表
注意这边结点的编号,是0~n-1,因此对第k个插入的点应当使用编号k-1。
#include <iostream>
using namespace std;
const int N = 100005;
// head存储链表头,e[]存储节点的值,nxt[]存储节点的next指针,idx表示当前用到了哪个节点
int head, val[N], nxt[N], idx;
// 初始化
void init() {
head = -1;
idx = 0;
}
// 在链表头插入一个数x
void insert_to_head(int x) {
val[idx] = x;
nxt[idx] = head;
head = idx ++ ;
}
// 在编号k的结点(第k+1个插入的结点)后面再插入一个数x
void insert(int k, int x) {
val[idx] = x;
nxt[idx] = nxt[k];
nxt[k] = idx;
idx ++ ;
}
// 将头结点删除,需要保证头结点存在
void remove_head(){
head = nxt[head];
}
// 将编号k的结点(第k+1个插入的结点)删除,需要保证编号k的结点存在
void remove(int k) {
nxt[k] = nxt[nxt[k]];
}
// 遍历链表
void ergodic() {
for (int i = head; i != -1; i = nxt[i]) {
int v = val[i];
printf("%d ", v);
}
}
int main() {
init();
int m;
scanf("%d", &m);
while(m -- ) {
int k, x;
char op;
cin >> op;
if (op == 'H') {
scanf("%d", &x);
insert_to_head(x);
}
else if (op == 'D') {
scanf("%d", &k);
if (k > 0) remove(k - 1);
else remove_head();
}
else if (op == 'I'){
scanf("%d%d", &k, &x);
insert(k - 1, x);
}
}
ergodic();
return 0;
}
2、双链表
注意这边设置0号结点,1号结点,这两节点没有数值,单纯代表头和尾。
因此插入结点编号是2~n+1,第k个插入的结点的编号就是k+1
#include <iostream>
using namespace std;
const int N = 100005;
// head存储链表头,e[]存储节点的值,l[]表示节点的左指针,r[]表示节点的右指针,idx表示当前用到了哪个节点
int val[N], l[N], r[N], idx;
// 初始化
void init() {
// 设置0号结点,1号结点,这两节点没有数值,单纯代表头和尾。
r[0] = 1, l[1] = 0; // 0号点右边是1号点,1号点左边是0号点。
idx = 2; // 初始已经有两节点
}
// 在编号k的结点右边再插入一个数x
void insert(int k, int x) {
val[idx] = x;
r[idx] = r[k]; l[idx] = k; // 新结点赋值
l[r[k]] = idx; r[k] = idx; // k结点修改,k右边的左节点换成新结点,k结点的右节点换成新节点
idx ++ ;
}
// 将编号k的结点删除,需要保证编号k的结点存在
void remove(int k) {
l[r[k]] = l[k]; // 右边的左结点连接左边
r[l[k]] = r[k]; // 左边的右结点连接右边
}
// 遍历链表
void ergodic() {
for (int i = r[0]; i != 1; i = r[i]) {
int v = val[i];
printf("%d ", v);
}
}
int main() {
init();
int m;
scanf("%d", &m);
while(m -- ) {
int k, x;
string op;
cin >> op;
if (op == "L") {
scanf("%d", &x);
insert(0, x); // 在头结点右边插入
}
else if (op == "R") {
scanf("%d", &x);
insert(l[1], x); // 在尾结点前一个结点的右边插入
}
else if (op == "D") {
scanf("%d", &k);
remove(k + 1); // 插入结点编号是2~n+1,因此第k个插入的结点编号就是k+1
}
else if (op == "IL"){
scanf("%d%d", &k, &x);
insert(l[k + 1], x); // 在k+1结点前一个结点的右边插入
}
else if (op == "IR"){
scanf("%d%d", &k, &x);
insert(k + 1, x); // 在k+1结点的右边插入
}
}
ergodic();
return 0;
}