前言
模拟单链表和双链表。
实际笔试中,为了效率,不会采用以下动态实现方式:
这里采用数组模拟链表,原因是:快
@yxc:比赛中为了运行效率,主要是用数组模拟邻接表。
数组模拟一个单链表
最常用的:邻接表,用以存储图和树。
Ex:最短路径问题、最小生成树问题、最大流问题 都是用邻接表存储的。
e[N]
表示某个点的值是多少,ne[N]
表示某个点的next指针是多少(下标),以下标关联起来。
acwing 826. 单链表
问题描述
实现一个单链表,链表初始为空,支持三种操作:
- 向链表头插入一个数;
- 删除第 k 个插入的数后面的数;
- 在第 k 个插入的数后插入一个数。
现在要对该链表进行 M 次操作,进行完所有操作后,从头到尾输出整个链表。
代码实现
单链表初始化
—>返回双链表一节
1 2 3 4 5 6 7 8 9 10 11 12
|
int head, e[N], ne[N], idx;
void init() { head = -1; idx = 0; }
|
将x插到头节点(最常用)
1 2 3 4 5 6 7 8 9
|
void add_to_head(int x) { ne[idx] = head head = idx; e[idx] = x; idex ++; }
|
将x插到下标是k的节点后面
1 2 3 4 5 6
| void add(int k, int x) { ne[idx] = ne[k]; ne[k] = idx; e[idx] = x; idx ++; }
|
将下标是k的后面节点删除
1 2 3
| void remove(int k) { ne[k] = ne[ne[k]]; }
|
完整代码
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
| #include <iostream>
using namespace std;
const int N = 100010;
int head, e[N], ne[N], idx;
void init() { head = -1; idx = 0; }
void insertHead(int x) { ne[idx] = head; head = idx; e[idx] = x; idx ++; }
void insert(int k, int x) { ne[idx] = ne[k]; ne[k] = idx; e[idx] = x; idx ++; }
void remove(int k) { ne[k] = ne[ne[k]]; }
int main() { int n; cin >> n; init(); while (n --) { char op; int k, x; cin >> op; if (op == 'H') { cin >> x; insertHead(x); } else if (op == 'D') { cin >> k; if (k == 0) head = ne[head]; else remove(k - 1); } else { cin >> k >> x; insert(k - 1, x); } } for (int i = head; i != -1; i = ne[i]) cout << e[i] << ' '; cout << endl; return 0; }
|
数组模拟双链表
双链表主要用以优化某些问题。
acwing 827.双链表
双链表初始化
下标是0的点:head头节点
下标是1的点:tail尾节点
这里与单链表不同,这里的头节点和尾节点是不储存数据的。
1 2 3 4 5 6 7
| int e[N], l[N], r[N], idx;
void init() { r[0] = 1, l[1] = 0; idx = 2; }
|
在节点a的右边插入节点x
1 2 3 4 5 6 7
| void insert(int a, int x) { e[idx] = x; r[idx] = r[a]; l[r[a]] = idx; l[idx] = a; r[a] = idx; idx ++; }
|
在节点a的左边插入节点x
删除节点a
1 2 3 4
| void remove(int a) { r[l[a]] = r[a]; l[r[a]] = l[a]; }
|
完整代码
问题描述见
aciwng 827.双链表
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
| #include <iostream>
using namespace std;
const int N = 100010;
int m; int e[N], l[N], r[N], idx;
void insert(int a, int x) { e[idx] = x; l[idx] = a, r[idx] = r[a]; l[r[a]] = idx, r[a] = idx ++ ; }
void remove(int a) { l[r[a]] = l[a]; r[l[a]] = r[a]; }
void init() { r[0] = 1, l[1] = 0; idx = 2; }
int main() { cin >> m; init();
while (m -- ) { string op; cin >> op; int k, x; if (op == "L") { cin >> x; insert(0, x); } else if (op == "R") { cin >> x; insert(l[1], x); } else if (op == "D") { cin >> k; remove(k + 1); } else if (op == "IL") { cin >> k >> x; insert(l[k + 1], x); } else { cin >> k >> x; insert(k + 1, x); } }
for (int i = r[0]; i != 1; i = r[i]) cout << e[i] << ' '; cout << endl;
return 0; }
|
📔博文图谱
提及本博文的链接