链表


1.单链表

数组实现的链表可以做指针实现的链表的所有事情,且数组实现的链表更快(静态链表),动态链表new操作太慢。

用数组模拟单链表,使用单链表构建一个邻接表(n个链表),用邻接表(最短路问题、最小生成树、最大流)进行存储图和树,

image-20230331091251965

1
2
3
int head;//头结点的next指针
int data[MAX], next[MAX];//结点数据data、下一个结点的下标next
int currt;//当前可用点的下标

2.双链表

用数组模拟双链表,双链表可用于优化某些问题,

image-20230331110238899

1
2
int dataa[MAX], left[MAX], right[MAX];//结点数据dataa、下一个结点的下标nextt
int currt;//当前可用点的下标

3.AcWing826.单链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<iostream>
using namespace std;

const int MAX = 100010;

int head;//头结点的next指针
int dataa[MAX], nextt[MAX];//结点数据dataa、下一个结点的下标nextt
int currt;//当前可用点的下标

void link_list_init() {
head = -1;
currt = 0;
}

void link_list_head_insert(int x) {
dataa[currt] = x;
nextt[currt] = head;
head = currt;
currt++;
}

void link_list_insert(int idx, int x) {
dataa[currt] = x;
nextt[currt] = nextt[idx];
nextt[idx] = currt;
currt++;
}

void link_list_delete(int idx) {
nextt[idx] = nextt[nextt[idx]];
}

int main() {
int m; cin >> m;
char op; int x, idx;
link_list_init();
while (m--) {
cin >> op;
switch (op) {
case 'H':
cin >> x;
link_list_head_insert(x);
break;
case 'D':
cin >> idx;
if (!idx) head = nextt[head];
link_list_delete(idx - 1);
break;
case 'I':
cin >> idx >> x;
link_list_insert(idx - 1, x);
break;
default:
cout << "input error!" << endl;
break;
}
}
for (int i = head; i != -1; i = nextt[i]) cout << dataa[i] << " ";
cout << endl;
return 0;
}

4.AcWing827.双链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include<iostream>
#include<string>
using namespace std;

const int MAX = 100010;

int dataa[MAX], leftt[MAX], rightt[MAX];//结点数据dataa、下一个结点的下标nextt
int currt;//当前可用点的下标

/* 0表示左端点 1表示右端点 */
void link_list_init() {
rightt[0] = 1;
leftt[1] = 0;
currt = 2;
}

void list_insert_head(int x) {
leftt[currt] = 0;
rightt[currt] = rightt[0];
dataa[currt] = x;
leftt[rightt[0]] = currt;
rightt[0] = currt;
currt++;
}

void list_insert_tail(int x) {
rightt[currt] = 1;
leftt[currt] = leftt[1];
dataa[currt] = x;
rightt[leftt[1]] = currt;
leftt[1] = currt;
currt++;
}

void list_delete(int idx) {
rightt[leftt[idx]] = rightt[idx];
leftt[rightt[idx]] = leftt[idx];
}

void list_insert_rightt(int idx, int x) {
leftt[currt] = idx;
rightt[currt] = rightt[idx];
dataa[currt] = x;
leftt[rightt[idx]] = currt;
rightt[idx] = currt;
currt++;
}

int main() {
int m; cin >> m;
string op; int x, idx;
link_list_init();
while (m--) {
cin >> op;
if (op == "L") {
cin >> x;
list_insert_head(x);
} else if (op == "R") {
cin >> x;
list_insert_tail(x);
} else if (op == "D") {
cin >> idx;
if (!idx) rightt[0] = rightt[rightt[0]];
list_delete(idx + 1);
} else if (op == "IR") {
cin >> idx >> x;
list_insert_rightt(idx + 1, x);
} else {
cin >> idx >> x;
list_insert_rightt(leftt[idx + 1], x);
}
}
for (int i = rightt[0]; i != 1; i = rightt[i]) cout << dataa[i] << " ";
cout << endl;
return 0;
}