基本数据结构
目录
- 1、线性数据结构
- 2、Rust特殊类型结构
线性数据结构
Rust 中的线性数据结构如下:
- 数组(Array):
[T; N] - 向量(Vec):
Vec<T> - 队列(Queue):
std::collections::VecDeque<T> - 双端队列(VecDeque):
VecDeque<T> - 链表:
LinkedList<T> - 栈(Stack):
Vec<T>或VecDeque<T>
1、数组
- 定义:
Array是Rust中的一种基本数据结构,表示固定长度的同构元素集合,类型为[T; N],其中T是元素类型,N是长度,在编译时确定。 - 内存分配:存储在栈上,内存是连续的,分配大小在编译时已知。
- 所有权:
Array是值类型。如果其元素实现了Copy trait(如i32),则数组也实现Copy,复制时不转移所有权;否则(如String),会转移所有权。 - 可变性:长度不可变,但元素可以通过可变绑定(
mut)修改。 - 使用场景:适合需要固定大小且数量已知的数据集合,例如坐标点、固定长度的缓冲区等。
- 性能:由于栈分配,访问和操作效率高,没有额外的内存管理开销。
2、向量
- 定义:
Vec是Rust标准库(std::vec)提供的一种动态数组,类型为Vec<T>,可以存储任意数量的同构元素。 - 内存分配:存储在堆上,通过
Rust的内存分配器管理,内存是连续的,支持动态调整大小。 - 所有权:
Vec是拥有者类型,拥有其元素的所有权。移动时(如赋值给新变量),原Vec不可用,除非元素是Copy类型。 - 可变性:长度和元素都可变,支持动态扩展(
push)和缩减(pop)等操作。 - 使用场景:适合需要运行时动态调整大小的数据集合,例如列表、队列或需要追加元素的场景。
- 性能:因堆分配,操作(如
push)平均时间复杂度为O(1),但当容量不足时需要重新分配内存,可能为O(n)。
Vec 内部维护三个主要字段:
- 指针:指向堆上分配的内存,存储实际元素。
- 长度:当前存储的元素数量(
len)。 - 容量:分配的内存能容纳的元素数量(
capacity)。 当len接近或超过capacity时,Vec会重新分配更大的内存(通常以2倍增长),并将现有元素复制到新内存。
用法示例+[实现]
3、队列
Rust 的标准库提供了 std::collections::VecDeque,这是一个高效的双端队列(double-ended queue),既支持队列的 FIFO 操作,也支持栈的 LIFO 操作,非常适合实现队列。
- 先进先出(FIFO):先入队的元素先出队。
- 线性结构:元素按顺序排列,尾部入队,头部出队。
- 高效首尾操作:入队(
push_back)和出队(pop_front)通常为O(1)。 - 单向访问:通常只访问头部(
front)或尾部添加,不支持随机访问。 - 动态大小:可动态增长或缩小。
- 有限容量(可选):可设置最大容量,超限需特殊处理。
- 线程安全性(视实现):
VecDeque非线程安全,需Mutex或用std::sync::mpsc。 - 变体:支持双端队列(
VecDeque)、优先级队列(BinaryHeap)等。
4、双端队列
- 双端操作:支持在队列头部和尾部进行添加(
push)和移除(pop)。 - 先进先出/后进先出:可实现
FIFO(队列)或LIFO(栈)行为。 - 高效首尾操作:头部和尾部操作(如
push_front、pop_front、push_back、pop_back)均摊复杂度为O(1)。 - 动态大小:可动态增长或缩小,元素数量不固定。
- 随机访问:支持通过索引访问任意元素(
O(1))。 - 内存连续:元素通常存储在连续内存中,缓存友好。
- 非线程安全:标准实现(如
VecDeque)需配合锁用于多线程。 - 灵活变体:可作为队列、栈或双端队列使用。
5、链表
- 动态结构:链表通过指针连接节点,允许动态分配和释放内存,适合大小不固定的数据。
- 非连续存储:节点在内存中不连续,插入和删除操作效率高(O(1)),但随机访问效率低(O(n))。
- 灵活性:支持单向、双向、循环等多种形式,适应不同场景。
- 空间开销:每个节点需额外存储指针,占用更多内存。
- 顺序访问:遍历需从头或尾开始,无法直接跳跃到任意节点。
6、栈
Rust 没有专门的栈类型或 API,但 Vec<T> 的 push、pop、last等方法提供了高效、封装好的栈操作,足以满足 LIFO 需求。
- LIFO 顺序:最后压入(
push)的元素最先弹出(pop),类似堆叠的盘子。 - 高效操作:压入(
push)和弹出(pop)操作通常为O(1)时间复杂度。 - 受限访问:只能操作栈顶元素,无法直接访问中间元素。
- 内存管理:栈通常在连续内存中实现(如数组)或通过链表实现,
Rust中常用Vec作为栈的底层结构。 - 用途:
- 函数调用管理(调用栈)。
- 表达式求值(如中缀转后缀)。
- 回溯算法(如深度优先搜索)。
- 撤销/重做功能。
特殊类型结构
切片
- 定义:切片是
Rust中用于访问连续数据子集的引用类型,分为字符串切片(&str)和数组切片(&[T])- 字符串切片(
&str):专门用于UTF-8编码的字符串数据,引用String或字符串字面量的一部分。 - 数组切片(
&[T]):引用数组、Vec<T>或其他连续序列的一部分,T是任意类型。
- 字符串切片(
- 特点:轻量、内存安全、不拥有数据,支持只读或可变访问。
- 使用场景:函数参数、字符串处理、数组操作、避免数据拷贝。
- 优势:结合
Rust的借用规则,切片提供高效、灵活的数据访问方式。
字符串
- 定义:
String是Rust标准库中用于动态、可变字符串的拥有类型,基于堆分配,支持UTF-8编码。 - 特点:拥有所有权、可变、动态增长,与
&str配合灵活。 - 使用场景:动态字符串构建、 字符串修改、 与切片配合、 多语言支持、 临时缓冲。