Files
rust/std/collections/readme.md
2026-03-11 09:12:14 +08:00

470 lines
4.8 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
在 Rust 里,`std::collections` 其实不只有 `HashMap``HashSet`。标准库给的集合虽然不多,但**每一个都很经典,而且用途非常明确**。整体大概可以分成三类:
1**哈希结构**
2**有序结构(树)**
3**队列 / 双端结构**
我给你**完整列一遍,并且说明用途和核心方法**。
---
# 一、Hash 类(你已经在用)
```rust
use std::collections::{HashMap, HashSet};
```
## 1 `HashMap<K,V>`
哈希表键值对。
特点:
* O(1) 平均查找
* 无序
* 最常用
常见用途:
* 字典
* 统计
* cache
你已经基本掌握。
---
## 2 `HashSet<T>`
哈希集合。
特点:
* 元素唯一
* 无序
* 基于 HashMap 实现
常见用途:
* 去重
* 集合运算
---
# 二、有序结构(基于红黑树)
```rust
use std::collections::{BTreeMap, BTreeSet};
```
Rust 标准库没有 `TreeMap`,而是 **BTree**
原因:
BTree 对 CPU cache 更友好。
---
## 3 `BTreeMap<K,V>`
有序 map。
特点:
* key 自动排序
* O(log n) 查询
例子:
```rust
use std::collections::BTreeMap;
let mut map = BTreeMap::new();
map.insert(3, "c");
map.insert(1, "a");
map.insert(2, "b");
for (k,v) in &map {
println!("{} {}", k, v);
}
```
输出:
```
1 a
2 b
3 c
```
---
### 常见方法
基本和 HashMap 一样:
```
insert
get
remove
contains_key
entry
```
但多了 **范围查询**
```rust
map.range(2..5)
```
这个功能非常强。
例如:
```rust
for (k,v) in map.range(10..20) {
}
```
---
### 使用场景
* 排序数据
* 区间查询
* ordered dictionary
---
## 4 `BTreeSet<T>`
有序集合。
特点:
* 自动排序
* 唯一元素
例子:
```rust
use std::collections::BTreeSet;
let mut set = BTreeSet::new();
set.insert(3);
set.insert(1);
set.insert(2);
for v in &set {
println!("{}", v);
}
```
输出:
```
1
2
3
```
---
# 三、队列结构
## 5 `VecDeque<T>`
双端队列。
```rust
use std::collections::VecDeque;
```
结构:
```
head -> circular buffer <- tail
```
特点:
* 两端 O(1) 插入删除
*`Vec` 更适合做队列
---
### 常见方法
插入:
```rust
push_back()
push_front()
```
删除:
```rust
pop_back()
pop_front()
```
查看:
```rust
front()
back()
```
例子:
```rust
let mut q = VecDeque::new();
q.push_back(1);
q.push_back(2);
q.push_front(0);
println!("{:?}", q);
```
---
### 使用场景
* BFS
* 任务队列
* sliding window
---
# 四、链表
## 6 `LinkedList<T>`
```rust
use std::collections::LinkedList;
```
双向链表。
操作:
```
push_back
push_front
pop_back
pop_front
```
例子:
```rust
let mut list = LinkedList::new();
list.push_back(1);
list.push_back(2);
list.push_front(0);
```
---
⚠️ Rust 官方建议:
**尽量不要用 LinkedList。**
原因:
* cache locality 差
* VecDeque 更快
除非:
* 频繁 splice
* 复杂链表操作
---
# 五、BinaryHeap非常重要
## 7 `BinaryHeap<T>`
```rust
use std::collections::BinaryHeap;
```
二叉堆。
默认:
```
最大堆
```
例子:
```rust
let mut heap = BinaryHeap::new();
heap.push(3);
heap.push(1);
heap.push(5);
println!("{:?}", heap.pop());
```
输出:
```
Some(5)
```
---
### 常见方法
```
push
pop
peek
len
is_empty
```
---
### 变成最小堆
使用:
```
std::cmp::Reverse
```
例子:
```rust
use std::cmp::Reverse;
let mut heap = BinaryHeap::new();
heap.push(Reverse(3));
heap.push(Reverse(1));
println!("{:?}", heap.pop());
```
---
### 使用场景
* Dijkstra
* 优先队列
* 调度系统
---
# 六、collections 全部结构总结
Rust 标准库集合其实只有 **7 个核心结构**
```
HashMap
HashSet
BTreeMap
BTreeSet
VecDeque
LinkedList
BinaryHeap
```
---
# 七、Rust collections 使用频率排行(真实项目)
大致是:
```
HashMap ⭐⭐⭐⭐⭐
VecDeque ⭐⭐⭐⭐
HashSet ⭐⭐⭐⭐
BinaryHeap ⭐⭐⭐
BTreeMap ⭐⭐
BTreeSet ⭐⭐
LinkedList ⭐
```
---
# 八、很多人不知道的一点
Rust **最常用容器其实是 `Vec`**
```
Vec<T>
```
但它在:
```
std::vec
```
不是 `collections`
原因:
Vec 太重要了,直接放 core。
---
# 九、如果你想系统练习 Rust collections
我非常推荐你写这几个小项目:
1**词频统计**
```
HashMap
```
2**LRU Cache**
```
HashMap + LinkedList
```
3**Dijkstra**
```
BinaryHeap
```
4**任务调度器**
```
BinaryHeap + HashMap
```
5**滑动窗口最大值**
```
VecDeque
```
---
如果你愿意,我可以再给你一个:
**🔥「Rust collections 深度指南90% Rust 程序员不知道的细节)」**
比如:
* 为什么 Rust 没有 `TreeMap`
* 为什么 `LinkedList` 几乎没人用
* `HashMap` 为什么这么快
* `BTreeMap` 内部结构其实不是二叉树
这些底层实现其实非常有意思。