数据结构与算法-Rust 版读书笔记-2线性数据结构-双端队列
1、双端队列
deque又称为双端队列,双端队列是与队列类似的项的有序集合。deque有两个端部:首端和尾端。deque不同于队列的地方就在于项的添加和删除是不受限制的,既可以从首尾两端添加项,也可以从首尾两端移除项。在某种意义上,这种混合线性结构提供了栈和队列的所有功能。
虽然deque拥有栈和队列的许多特性,但其不需要像它们一样强制地进行LIFO和FIFO排序,这取决于如何添加和删除数据。deque既可以当作栈使用,也可以当作队列使用,但最好不要如此,因为不同的数据结构都有自身的特性,它们均是为了不同的计算目的而设计的。
2、双端队列的 Rust 代码实现、运行结果
queue.rs
/** @Description: * @Author: tianyw* @Date: 2023-12-10 17:43:34* @LastEditTime: 2023-12-11 22:19:06* @LastEditors: tianyw*/
// 定义队列
#[derive(Debug)]pub struct Deque<T> { // pub 表示公开的cap: usize, // 容量data: Vec<T>, // 数据容器
}impl<T> Deque<T> { // impl 用于定义类型的实现,如实现 new 方法、is_empty 方法等// 初始化空栈pub fn new(cap: usize) -> Self { Self {cap: cap,data:Vec::with_capacity(cap)}}pub fn is_empty(&self) -> bool {0 == self.len()}pub fn is_full(&self) -> bool {self.len() == self.cap}pub fn len(&self) -> usize { // &self 只可读self.data.len()}// 清空pub fn clear(&mut self) { // &mut self 可读、可写self.data = Vec::with_capacity(self.cap)}// Vec 的末尾为队首pub fn add_front(&mut self, val: T) -> Result<(), String> {if self.len() == self.cap {return Err("No space available".to_string());}self.data.push(val);Ok(())}// Vec 的首部为队尾pub fn add_rear(&mut self,val: T) -> Result<(), String> {if self.len() == self.cap {return Err("No space available".to_string());}self.data.insert(0,val);Ok(())}// 从队首移除数据pub fn remove_front(&mut self) -> Option<T> {if self.len() > 0 {self.data.pop()}else {None}}// 从队尾移除数据pub fn remove_rear(&mut self) -> Option<T> {if self.len() > 0 {Some(self.data.remove(0))}else {None}}// 以下是为双端队列实现的迭代功能// into_iter:双端队列改变,成为迭代器// iter: 双端队列不变,得到不可变迭代器// iter_mut: 双端队列不变,得到可变迭代器pub fn into_iter(self) -> IntoIter<T> {IntoIter(self)}pub fn iter(&self) -> Iter<T> {let mut iterator = Iter { stack: Vec::new() };for item in self.data.iter() {iterator.stack.push(item);}iterator}pub fn iter_mut(&mut self) -> IterMut<T> {let mut iterator = IterMut { stack: Vec::new() };for item in self.data.iter_mut() {iterator.stack.push(item);}iterator}}// 实现三种迭代功能
pub struct IntoIter<T>(Deque<T>);
impl<T:Clone> Iterator for IntoIter<T> {type Item = T;fn next(&mut self) -> Option<Self::Item> {// 元组的第一个元素不为空if !self.0.is_empty() {Some(self.0.data.remove(0))} else {None}}
}pub struct Iter<'a,T:'a> { stack: Vec<&'a T>, }
impl<'a,T> Iterator for Iter<'a,T> {type Item = &'a T;fn next(&mut self) -> Option<Self::Item> {if 0 != self.stack.len() {Some(self.stack.remove(0)) // 索引移除}else {None}}
}pub struct IterMut<'a,T:'a> { stack: Vec<&'a mut T> }
impl<'a,T> Iterator for IterMut<'a,T> {type Item = &'a mut T;fn next(&mut self) -> Option<Self::Item> {if 0 != self.stack.len() {Some(self.stack.remove(0))}else {None}}
}
main.rs
/** @Description:* @Author: tianyw* @Date: 2023-12-11 21:29:04* @LastEditTime: 2023-12-11 22:21:01* @LastEditors: tianyw*/mod deque;
fn main() {basic();iter();fn basic() {let mut d = deque::Deque::new(4);let _r1 = d.add_front(1);let _r2 = d.add_front(2);let _r3 = d.add_rear(3);let _r4 = d.add_rear(4); // 入队if let Err(error) = d.add_front(5) {println!("Enqueue error:{error}")}println!("{:?}",d);match d.remove_rear() {Some(data) => println!("remove rear data {data}"),None => println!("empty deque"),}match d.remove_front() {Some(data) => println!("remove front data {data}"),None => println!("empty deque"),}println!("empty: {},len: {}",d.is_empty(),d.len());println!("full: {},{:?}",d.is_full(),d);d.clear();println!("{:?}",d);}fn iter() {let mut d = deque::Deque::new(4);let _r1 = d.add_front(1);let _r2 = d.add_front(2);let _r3 = d.add_rear(3);let _r4 = d.add_rear(4);let sum1 = d.iter().sum::<i32>();let mut addend = 0;for item in d.iter_mut() {*item += 1;addend += 1;}let sum2 = d.iter().sum::<i32>(); // vec 的 sum 方法println!("{sum1} + {addend} = {sum2}");assert_eq!(14,d.into_iter().sum::<i32>());}
}
cargo run 运行结果
应用:回文检测
// palindrome_checker.rsfn palindrome_checker(pal: &str) -> bool {// 数据入队let mut d = Deque::new(pal.len());for c in pal.chars() {let _r = d.add_rear(c);}let mut is_pal = true;while d.size() > 1 && is_pal {// 出队首尾字符let head = d.remove_front();let tail = d.remove_rear();// 比较首尾字符,若不同,则字符串非回文if head != tail {is_pal = false;}}is_pal
}fn main() {let pal = "rustsur";let is_pal = palindrome_checker(pal);println!("{pal} is palindrome string: {is_pal}");// 输出“rustsur is palindrome string: true”let pal = "panda";let is_pal = palindrome_checker(pal);println!("{pal} is palindrome string: {is_pal}");// 输出“panda is palindrome string: false”
}