数据结构与算法-Rust 版读书笔记-2线性数据结构-双端队列

数据结构与算法-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.rs
 
fn 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”
}

猜你喜欢

转载自blog.csdn.net/yinweimumu/article/details/134937928
今日推荐