笔记-Rust常用集合类型

374 阅读3分钟

常用集合类型

常用集合类型有:

  • 线性序列: 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);
    }
}