常用集合类型
常用集合类型有:
- 线性序列: Vec,VecDeque,LinkedList
- Key-Value 映射表: HashMap,BTreeMap
- 集合类型: HashSet,BTreeSet
- 优先队列: BinaryHeap
线性序列
向量 Vec
- 向量类似数组,但是可以动态增长
- 常见初始化方式有:
vec![1,3],Vec::new(), Vec::with_capacity(5)。
fn main() {
let mut v1:Vec<i32> = Vec::with_capacity(5);
v1.push(1);
v1.push(2);
println!("v1[1] = {}", v1[1]);
println!("v1.get(1) = {}", v1.get(1).unwrap());
v1.drain(0..=0);
println!("v1 = {:?}", v1);
println!("v1.pop() = {:?}", v1.pop());
}
双端队列 VecDeque
- deque 是 double ended queue 的缩写。
- 双端队列中的元素可以从两端弹出,插入和删除操作被限定在两端进行。
fn main() {
let mut dq: VecDeque<i32> = VecDeque::new();
dq.push_front(1);
dq.push_front(2);
dq.push_back(6);
dq.push_back(9);
println!("dq = {:?}", dq); // dq = [2, 1, 6, 9]
println!("dq.get(0).unwrap() = {}", dq.get(0).unwrap()); // dq.get(0).unwrap() = 2
println!("dq.get(1).unwrap() = {}", dq.get(1).unwrap()); // dq.get(1).unwrap() = 1
println!("dq = {:?}", dq); // dq = [2, 1, 6, 9]
println!("dq.front().unwrap() = {}", dq.front().unwrap()); // dq.front().unwrap() = 1
println!("dq.front().unwrap() = {}", dq.front().unwrap()); // dq.front().unwrap() = 1
println!("dq.back().unwrap() = {}", dq.back().unwrap()); // dq.back().unwrap() = 9
println!("dq.back().unwrap() = {}", dq.back().unwrap()); // dq.back().unwrap() = 9
println!("dq.pop_back() = {:?}", dq.pop_back()); // dq.pop_back() = Some(9)
println!("dq.pop_front() = {:?}", dq.pop_front()); // dq.pop_front() = Some(2)
println!("dq = {:?}", dq); // dq = [1, 6]
dq.push_back(8);
dq.push_back(9);
println!("dq = {:?}", dq); // dq = [1, 6, 8, 9]
dq.remove(2); // 低效率操作,因为是 Vec。
println!("dq = {:?}", dq); // dq = [1, 6, 9]
}
链表
- Rust 的链表是双向链表,允许在两端进行插入或弹出元素。
- 与 Vec / VecDeque 相比,删除效率高,别的没想到优势场景。
fn main() {
let mut list = LinkedList::new();
list.push_front(1);
list.push_front(2);
list.push_back(3);
list.push_back(4);
println!("list = {:?}", list); // list = [2, 1, 3, 4]
// list.remove(2); // unstable version method
list.pop_front();
list.pop_back();
println!("list = {:?}", list); // list = [1, 3]
}
Key-Value 哈希映射表
- Rust 集合模块 提供了两种 哈希映射表。
- std::collections::HashMap 要求key是可哈希的。
- std::collections::BTreeMap 要求key是可排序的。
fn main() {
let mut hmap = HashMap::new();
hmap.insert(3, 'c');
hmap.insert(1, 'a');
hmap.insert(2, 'b');
hmap.insert(5, 'e');
hmap.insert(4, 'd');
println!("hmap = {:?}", hmap); // hmap = {5: 'e', 3: 'c', 1: 'a', 2: 'b', 4: 'd'}
for item in hmap.iter() {
println!("item = {:?}", item);
}
let mut bmap = BTreeMap::new();
bmap.insert(3, 'c');
bmap.insert(2, 'b');
bmap.insert(1, 'a');
bmap.insert(5, 'e');
bmap.insert(4, 'd');
println!("bmap = {:?}", bmap); // bmap = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}
for item in bmap.iter() {
println!("item = {:?}", item); // 输出内容的顺序是按照 key 排好序的。
}
}
集合: HashSet 和 BTreeSet
- HashSet<T> 和 BTreeSet<T> 等价于 HashMap<T, ()> 和 BTreeMap<T, ()>。
- 集合中的元素应该是唯一的。
- HashSet 应该是无序的, BTreeSet 应该是有序的。
fn main() {
let mut hset = HashSet::new();
hset.insert("Shanghai");
hset.insert("Beijing");
hset.insert("Guangzhou");
hset.insert("Beijing");
for item in hset.iter() {
println!("hset_item = {}", item);
}
println!(
"hset.contains(\"Shanghai\") = {:?}",
hset.contains("Shanghai")
);
let mut bset = BTreeSet::new();
bset.insert("Shanghai");
bset.insert("Beijing");
bset.insert("Guangzhou");
for item in bset.iter() {
println!("bset_item = {}", item);
}
println!(
"bset.contains(\"Guangzhou\") = {:?}",
hset.contains("Guangzhou")
);
println!(
"bset.contains(\"Wulumuqi\") = {:?}",
hset.contains("Wulumuqi")
);
}
优先队列
Rust 提供的优先队列是 BinaryHeap (二叉最大堆)。
-
二叉堆是一种特殊的二叉树,能高效、快速地找出最大值和最小值,常被应用于优先队列,也被用于著名的堆排序算法中,它有两个特性:
-
结构特性:它是一棵完全二叉树,表示树的每一层都有左侧和右侧子节点(除了最后一层的叶节点),并且最后一层的叶节点尽可能都是左侧子节点。
-
堆特性:二叉堆不是最小堆就是最大堆。最小堆允许你快速提取树的最小值,最大堆允许你快速提取树的最大值。所有的节点都大于等于(最大堆)或小于等于(最小堆)每个它的子节点。
fn main() {
let mut heap: BinaryHeap<i32> = BinaryHeap::new();
println!("heap.peek() = {:?}", heap.peek());
let arr = [15, 18, 30, 35, 36, 45];
for i in arr {
heap.push(i);
}
println!("heap.peek() = {:?}", heap.peek());
println!("heap.peek() = {:?}", heap.peek());
while let Some(j) = heap.pop() {
println!("j = {}", j);
}
}