链表
链表
当你使用数组删除其中某个节点时,通常需要将后面的节点全部向前移动,这样不仅很麻烦还时间复杂度高。
链表就弥补了删除时间复杂度高的缺点,他的删除操作和插入操作只需要 \(O(1)\) 的时间复杂度,但有优势就有劣势,链表的查询和修改操作都需要 \(O(n)\) 的时间复杂度。
链表的存储可以是连续的,也可以是分散在内存中的,链表分为单向链表和双向链表。
单向链表只可以知道自己的下一个元素,不知道自己的上一个元素是什么;而双向链表可以知道自己的上一个元素可下一个元素。
单向链表只有一个遍历方向,但双向链表有两个遍历方向。在需要频繁访问前几个节点或后几个节点的情况下使用双向链表会更为方便。
使用链表时,可以直接使用STL库中的链表 list ,也可以写静态链表和动态链表。
动态链表
动态链表需要临时分配链表节点,使用完毕后释放节点。
题目: P1996 约瑟夫问题 - 洛谷
code:
#include<bits/stdc++.h>
using namespace std;
struct node {
int data;
node *next;
};
int n, m;
signed main() {
cin >> n >> m;
node *head, *p, *now, *prev;
head = new node;
head -> data = 1;
head ->next = NULL;
now = head;
for(int i = 2;i <= n;i ++) {
p = new node;
p -> data = i;
p -> next = NULL;
now -> next = p;
now = p;
}
now -> next = head;
prev = now, now = head;
while((n --) > 1) {
for(int i = 1;i < m;i ++) {
prev = now;
now = now -> next;
}
cout << now -> data << " ";
prev -> next = now -> next;
delete now;
now = prev -> next;
}
cout << now -> data;
delete now;
}
静态链表
静态链表实际上是一段 提前分配 好了的一段 连续 的空间来实现的链表,这就是我们之前说的 链表的存储可以是连续的。
具体有两种做法:
- 定义链表结构体数组,和动态链表差不多,只是不用去新开内存;
- 使用一维数组,直接在数组上进行链表的操作。
代码不放了
STL 实现双端链表
STL 是一个属于c++的好东西,它由标准模板STL库统一管理。
STL里的双端队列是 list ,可以通过指针访问节点数据,高效率的删除和插入。
使用方法:
- 声明(定义)列表
list<int> l定义一个列表l - 插入元素
l.push_back(value)插入元素value - 删除尾部元素
l.pop_back(); - 删除元素 \(i\)
l.erase(i); - 访问尾部元素
l.back() - 访问头部元素
l.front()
块状链表
咕咕咕

浙公网安备 33010602011771号