數據結構與算法-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.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”
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/214534.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/214534.shtml
英文地址,請注明出處:http://en.pswp.cn/news/214534.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue3封裝接口

在src下面創建一個文件夾任意名稱 我拿這個名字舉例子了apiService 相當于創建一個新的文件 // 封裝接口 // apiService.js import axios from axios;// 接口前綴 const API_BASE_URL 前綴;接口后綴export const registerUser async (fileData) > {try {const response …

數據分析 | 頻率編碼和標簽編碼 | Python代碼

數據集見GitHub鏈接&#xff1a;https://github.com/ChuanTaoLai/Frequency-Encoding-And-Label-Encoding 標簽編碼&#xff1a; import pandas as pd from sklearn.preprocessing import LabelEncoderdata1 pd.read_excel(rD:\0文獻整理\網絡入侵檢測\KDD99\KDDTrain.xlsx) …

透析跳躍游戲

關卡名 理解與貪心有關的高頻問題 我會了?? 內容 1.理解跳躍游戲問題如何判斷是否能到達終點 ?? 2.如果能到終點&#xff0c;如何確定最少跳躍次數 ?? 1. 跳躍游戲 leetCode 55 給定一個非負整數數組&#xff0c;你最初位于數組的第一個位置。數組中的每個元素代表…

微信商家收款碼扣多少手續費

很多人想申請低手續費率的收款碼不知從何下手&#xff0c;在參考了大量博客教學之后&#xff0c;終于搞懂了詳細流程以及注意事項。在此記錄一下。我申請的是一個只需要0.2%費率的微信收款碼&#xff0c;申請時間是2022年2月12日。申請之前只需要準備營業執照和法人身份z&#…

JSON在線解析

JSON在線解析及格式化驗證 - JSON.cn JSON在線視圖查看器(Online JSON Viewer)

java中list的addAll用法詳細實例?

List 的 addAll() 方法用于將一個集合中的所有元素添加到另一個 List 中。下面是一個詳細的實例&#xff0c;展示了 addAll() 方法的使用&#xff1a; java Copy code import java.util.ArrayList; import java.util.List; public class AddAllExample { public static v…

設計模式: 關于編程范式的聲明式和命令式編程及應用框架的開發和設計原則

編程范式 命令式編程聲明式編程 上述兩種范式是相對來說的 命令式編程 詳細描述做事過程的方式就可以叫做 命令式例子: 張三媽媽讓張三買食鹽 拿錢&#xff0c;開門&#xff0c;下樓&#xff0c;到商店&#xff0c;付款&#xff0c;帶著食鹽回家 例子&#xff1a;在指定div…

驗證二叉搜索樹[中等]

優質博文&#xff1a;IT-BLOG-CN 一、題目 給你一個二叉樹的根節點root&#xff0c;判斷其是否是一個有效的二叉搜索樹。有效 二叉搜索樹定義如下&#xff1a; 【1】節點的左子樹只包含 小于 當前節點的數。 【2】節點的右子樹只包含 大于 當前節點的數。 【3】所有左子樹和右…

Leetcode 40 組合總和 II

題意理解&#xff1a; 每個數字在每個組合中只能使用 一次 數字可以重復——>難點&#xff08;如何去重&#xff09; 每個組合和target 求組合&#xff0c;對合限制&#xff0c;考慮回溯的方法。——將其抽象為樹結構。 樹的寬度——分支大小 樹的深度——最…

Spring IoC和DI

目錄 一. Spring是什么 IoC DI 二. IoC&DI的使用 IoC 1.Controller&#xff08;控制器存儲&#xff09; 2.Service&#xff08;服務存儲&#xff09; 3.Repository&#xff08;倉庫存儲&#xff09; 4.Componemt&#xff08;組件存儲&#xff09; 5.Configuratio…

解決Could not establish connection to : XHR failed

解決Could not establish connection to : XHR failed 問題描述 用vscode用遠程連接服務器時總報上面的錯誤&#xff0c;用xshell和Xftp和vscode終端都可以連上&#xff0c;但是用vscode的ssh連接缺總報錯&#xff0c;導致無法連接服務器進行代碼調試 一、原因 原因可能是在…

【MATLAB】 數據、矩陣、行、列翻轉

1.MATLAB函數fliplr 用法&#xff1a;fliplr(X) 功能&#xff1a;matlab中的fliplr函數實現矩陣的左右翻轉。 fliplr(X)使矩陣X沿垂直軸左右翻轉。 相關函數&#xff1a;flipud函數可以實現矩陣的上下翻轉。 備注&#xff1a;matlab中提供了許多對矩陣操作的函數&#xff0c;可…

Go json 差異比較 json-diff(RFC6902)

Go json 差異比較 json-diff(RFC 6902) 畢業設計中過程中為了比較矢量圖的差異而依據 RFC 6902 編寫的一個包&#xff0c;現已開源&#xff1a; Json-diff 使用 go get -u github.com/520MianXiangDuiXiang520/json-diff序列化與反序列化 與官方 json 包的序列化和反序列化不…

后端開發面試題

這是一波今年7月份的大廠面試題&#xff0c;分享下&#xff5e;&#xff5e; Mybatis三級緩存 Mybatis懶加載 分布式事務 transaction gradle和maven區別 抽象類、多態 Springboot啟動 ConcurrentHashMap 樂觀鎖、悲觀鎖 docker k8s常用命令 電商業務從什么維度分庫分…

AcWing 95. 費解的開關(遞推)

題目鏈接 活動 - AcWing 本活動組織刷《算法競賽進階指南》&#xff0c;系統學習各種編程算法。主要面向有一定編程基礎的同學。https://www.acwing.com/problem/content/97/ 題解 只要第一行開關的狀態確定&#xff0c;則所有開關的狀態都可以被推出來。第一行開關總共有種操…

jemeter,同一線程組內,調用cookie實現接口關聯

取cookie方式參考上一篇&#xff1a;jemeter&#xff0c;取“臨時重定向的登錄接口”響應頭中的cookie-CSDN博客 元件結構 登錄后要執行的接口為“api/get_event_list/”&#xff0c;在該HTTP請求下創建HTTP信息頭管理器&#xff0c;配置如下&#xff1a; 執行測試后&#xff0…

【ensp實踐】eNSP實戰篇(4)用eNSP實驗來認識什么是OSPF及OSPF配置?

OSPF目錄 寫在前面涉及知識一、什么是OSPF&#xff1f;二、OSPF特性&#xff08;優缺點&#xff09;2.1 OSPF優點2.2 OSPF缺點 三、OSPF實驗3.1 打開ensp&#xff0c;添加設備3.2 建立連線3.3 配置及ospf命令【核心】3.3.1 配置PC機3.3.2 設置命令 3.4 驗證效果3.4.1、驗證OSPF…

Spring IoC如何存取Bean對象

小王學習錄 IoC(Inversion of Control)1. 什么是IoC2. 什么是Spring IoC3. 什么是DI4. Spring IoC的作用 存儲Bean對象1. 創建Bean2. 將Bean注冊到Spring中. 取Bean對象.1. 獲取Spring上下文信息使用ApplicationContext和BeanFactory的區別 2. 獲取指定Bean對象 IoC(Inversion …

使用JLink仿真器實現調試打印的N種方法

方法一&#xff1a;使用MCU的串口 這是最古老也是最簡單的方法。 電腦上面插一個USB轉TTL&#xff0c;然后與MCU的UART_RX/UART_TX/GND連接起來。PC端再打開一個串口調試助手。兩邊的波特率一致&#xff0c;就可以收到MCU發過來的打印信息了。 方法二&#xff1a;使用JLink仿…