C++中std::deque詳解和實戰工程代碼示例

C++中std::deque詳解和實戰工程代碼示例

std::deque(雙端隊列)是 C++ 標準庫中的一個序列容器,與 std::vector 類似,但它支持從頭部和尾部高效地插入和刪除元素。它底層采用分段連續空間實現,兼具靈活性與性能。


一、基本特性

特性描述
隨機訪問支持下標訪問(operator[]at()
快速頭尾操作push_frontpush_back 效率高,優于 vector 的頭部插入
分段存儲結構非一塊連續內存,適合頻繁的插入刪除場景
迭代器失效規則插入刪除可能導致部分迭代器失效,需小心

二、使用注意事項(易錯點)

1. vector 的差異

  • std::deque 并不保證所有元素在一塊連續內存中存儲,不能通過 &deque[0] 獲取整個數組地址。
  • 不適合與 C 風格 API 一起使用(比如 memcpy(&deque[0], ...) 可能導致未定義行為)。

2. 迭代器失效

  • 插入或刪除任意位置的元素都會使所有迭代器失效,不同于 vector 只在 reallocation 時失效。
std::deque<int> dq = {1, 2, 3, 4};
auto it = dq.begin();
dq.push_front(0); // it 現在已失效!

3. 頻繁中間插入性能低

  • 插入/刪除位于中間位置的元素效率低,需移動大量元素。
  • 如需頻繁中間插入,建議使用 std::list

4. 容量管理

  • 沒有 capacity() 函數(不像 vector),不能預留空間,使用方式略有不同。

5. 對象構造開銷

  • 每次插入都可能涉及對象構造和移動,注意對象拷貝開銷。

三、常用操作代碼示例

示例 1:基本使用

#include <iostream>
#include <deque>int main() {std::deque<int> dq;dq.push_back(1);   // 尾部插入dq.push_front(0);  // 頭部插入dq.push_back(2);for (int val : dq)std::cout << val << " ";  // 輸出:0 1 2dq.pop_front();  // 刪除頭部dq.pop_back();   // 刪除尾部std::cout << "\nFront: " << dq.front();  // 輸出:1std::cout << "\nBack: " << dq.back();    // 輸出:1
}

示例 2:模擬滑動窗口(典型應用)

#include <deque>
#include <vector>
#include <iostream>std::vector<int> maxSlidingWindow(const std::vector<int>& nums, int k) {std::deque<int> dq;  // 存索引std::vector<int> result;for (int i = 0; i < nums.size(); ++i) {while (!dq.empty() && dq.front() <= i - k)dq.pop_front();  // 移除滑出窗口的元素while (!dq.empty() && nums[dq.back()] < nums[i])dq.pop_back();   // 保持單調性dq.push_back(i);if (i >= k - 1)result.push_back(nums[dq.front()]);}return result;
}

四、實際應用場景

場景使用原因
滑動窗口算法快速刪除/插入頭尾元素
限長隊列(日志、緩存)自動彈出舊元素,控制內存
多線程任務隊列(需加鎖)支持雙端插入,配合 mutex 使用
狀態機緩沖器記錄有限長度狀態序列

五、工程應用實戰

下面是兩個典型 std::deque 實戰場景的完整示例代碼,適合用于滑動窗口最大值算法和限長隊列(比如日志或緩存)實現。

示例一:滑動窗口最大值(單調隊列優化)

用于處理如:[1,3,-1,-3,5,3,6,7],滑動窗口大小 k=3 時,每個窗口內的最大值。

功能說明:

  • 保持一個單調遞減隊列(deque中存下標)。
  • 窗口滑動時移除已滑出的元素。
  • 每次窗口滿了就將最大值加入結果。

示例代碼:

#include <iostream>
#include <vector>
#include <deque>std::vector<int> maxSlidingWindow(const std::vector<int>& nums, int k) {std::deque<int> dq;std::vector<int> result;for (int i = 0; i < nums.size(); ++i) {// 移除滑出窗口的元素if (!dq.empty() && dq.front() <= i - k)dq.pop_front();// 保持隊列單調遞減(移除小于當前值的)while (!dq.empty() && nums[dq.back()] < nums[i])dq.pop_back();dq.push_back(i);  // 存下標if (i >= k - 1)result.push_back(nums[dq.front()]);}return result;
}int main() {std::vector<int> nums = {1,3,-1,-3,5,3,6,7};int k = 3;auto result = maxSlidingWindow(nums, k);std::cout << "滑動窗口最大值:";for (int val : result)std::cout << val << " ";  // 輸出:3 3 5 5 6 7std::cout << std::endl;
}

示例二:限長隊列(固定大小緩存或日志)

模擬一個最大容量為 N 的隊列,插入新元素時若超過容量,自動從頭部彈出舊元素。

功能說明:

  • 封裝成 LimitedQueue<T> 模板類
  • 支持 push()pop()size()front()back() 等基本操作

示例代碼:

#include <iostream>
#include <deque>template <typename T>
class LimitedQueue {
public:LimitedQueue(size_t capacity) : max_size(capacity) {}void push(const T& value) {if (dq.size() >= max_size)dq.pop_front();  // 超出容量,彈出舊元素dq.push_back(value);}void print() const {for (const auto& item : dq)std::cout << item << " ";std::cout << "\n";}size_t size() const { return dq.size(); }private:std::deque<T> dq;size_t max_size;
};int main() {LimitedQueue<int> q(5);  // 最多保存 5 個元素for (int i = 1; i <= 10; ++i) {q.push(i);std::cout << "插入 " << i << " 后隊列內容:";q.print();}
}

輸出示例:

插入 1 后隊列內容:1 
插入 2 后隊列內容:1 2 
插入 3 后隊列內容:1 2 3 
插入 4 后隊列內容:1 2 3 4 
插入 5 后隊列內容:1 2 3 4 5 
插入 6 后隊列內容:2 3 4 5 6 
插入 7 后隊列內容:3 4 5 6 7 
...

六、與其他容器對比

特性vectordequelist
隨機訪問???
快速尾部插入?(均攤常數)??
快速頭部插入?(O(n))??
中間插入/刪除?(慢)?(稍快)?(快)
內存連續性??(分段)?

七、建議與最佳實踐

  • 推薦用于: 需要雙端插入/刪除,且訪問頻率較高的場景。
  • 避免: 中間頻繁插入、與 C 接口配合使用。
  • 調試時: 注意調試器中 deque 不總能完整顯示所有元素(因為分段結構)。

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

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

相關文章

【AI大模型入門指南】概念與專有名詞詳解 (二)

【AI大模型入門指南】概念與專有名詞詳解 &#xff08;二&#xff09; 一 、前言 當你和聊天機器人聊得天花亂墜時&#xff0c;當你用文字讓AI生成精美圖片時&#xff0c;當手機相冊自動幫你分類照片時 —— 這些看似智能的操作背后&#xff0c;都藏著 AI 大模型的身影。 本…

AIStor 的模型上下文協議 (MCP) 服務器:管理功能

在本系列的上一篇博文中&#xff0c;我們討論了 MinIO AIStor 的模型上下文協議 (MCP) 服務器的基本用戶級功能。我們學習了如何使用人類語言命令查看存儲桶的內容、分析對象并標記它們以便將來處理&#xff0c;以及如何通過 LLM&#xff08;例如 Anthropic Claude&#xff09;…

期權末日輪實值期權盈利未平倉怎么辦?

本文主要介紹期權末日輪實值期權盈利未平倉怎么辦&#xff1f;期權末日輪實值期權盈利未平倉該怎么辦&#xff0c;需要明確幾個關鍵點&#xff1a;末日輪指的是期權到期日臨近的時候&#xff0c;通常指最后一周&#xff0c;尤其是最后一天&#xff0c;這時候時間價值衰減很快&a…

C++/Qt 聯合編程中的定時器使用陷阱:QObject::startTimer 報錯詳解

在 Qt 開發中&#xff0c;QTimer 是一個常用的工具類&#xff0c;用于處理定時事件。但不少開發者在 C/Qt 聯合編程&#xff0c;尤其是在工具類、靜態類、線程中使用定時器時&#xff0c;會遇到如下令人困惑的報錯&#xff1a; QObject::startTimer: Timers can only be used …

CentOS7.9 查詢運維安全日志,排查惡意用戶

1、查看系統版本 cat /etc/redhat-release uname -a 2、查看所有賬號 cat /etc/shadow 3、修改 root 密碼 passwd 3、查看賬號ID id jinzhi 4、查看登錄日志 lastlog 5、查看操作日志 cat .bash_history sudo cat /home/yunwei/.bash_history sudo grep root /va…

多模態大語言模型arxiv論文略讀(117)

Training-free Zero-shot Composed Image Retrieval via Weighted Modality Fusion and Similarity ?? 論文標題&#xff1a;Training-free Zero-shot Composed Image Retrieval via Weighted Modality Fusion and Similarity ?? 論文作者&#xff1a;Ren-Di Wu, Yu-Yen L…

如何正確的配置eureka server集群

將 Eureka Server 實例的 hostname 都配置成相同的值&#xff0c;在 Eureka Server 集群環境下同樣是不推薦且通常會導致嚴重問題的&#xff0c; 核心問題&#xff1a;Eureka Server 集群的工作機制 Eureka Server 集群通過相互注冊&#xff08;Peering&#xff09;來實現高可…

AI支持下的-ArcGIS數據處理、空間分析、可視化及多案例綜合應用

查看原文>>> 從入門到精通-AI支持下的-ArcGIS數據處理、空間分析、可視化及多案例綜合應用 結合ArcGIS和GPT的優勢&#xff0c;本文重點進行AI大模型應用、ArcGIS工作流程及功能、Prompt使用技巧、AI助力工作流程、AI助力數據讀取與處理、AI助力空間分析、AI助力遙感…

vue3-ts: v-model 和 props 的關系

在 Vue.js 中&#xff0c;v-model 是一個語法糖&#xff0c;它實際上是 :value 和 input 事件的組合。 當你使用 v-model 綁定一個組件時&#xff0c;默認情況下&#xff0c;組件會通過 props 接收 value 這個 prop&#xff0c; 并通過觸發 input 事件來更新父組件中的數據。 …

學車筆記 變擋

超15就可以加一檔了 有些人對手動擋的檔位有一些誤解_嗶哩嗶哩_bilibili 獻給所有新司機.開手動檔擺脫頓挫的根本方法.學會看轉速!沒那么復雜!_嗶哩嗶哩_bilibili 減速到怠速降一檔

STM32的DMA簡介

STM32的DMA簡介 一、DMA概述 DMA&#xff08;Direct Memory Access&#xff0c;直接存儲器存取&#xff09;是一種硬件機制&#xff0c;它允許外設和存儲器之間或者存儲器和存儲器之間進行高速數據傳輸&#xff0c;而無需CPU的干預。這種機制可以極大地節省CPU資源&#xff0c…

Spring-AOP知識點

一、AOP簡介 1.AOP概念 2.AOP思想實現方案 3.AOP相關概念 二、基于xml配置AOP 1.快速入門 2.AOP配置詳解 3.AOP原理剖析 三、基于注解配置AOP 1.快速入門 2.注解方式AOP配置詳解 抽取切點表達式

Java@Data 與 @NotNull 注解沖突問題

第一章&#xff1a;核心概念解析 1. Data&#xff08;Lombok 提供&#xff09; 自動生成以下方法&#xff1a; gettersettertoString()equals()hashCode() 簡化實體類編寫&#xff0c;提高開發效率。 示例&#xff1a; import lombok.Data;Data public class User {private…

離線部署openstack 2024.1 glance

控制節點鏡像服務 離線下載 apt install --download-only glancemkdir /controller/glance mv /var/cache/apt/archives/*.deb /controller/glance/ dpkg -i /controller/glance/*.deb在一個控制節點操作 CREATE DATABASE glance; GRANT ALL PRIVILEGES ON glance.* TO glan…

.NET AOT 詳解

簡介 AOT&#xff08;Ahead-Of-Time Compilation&#xff09;是一種將代碼直接編譯為機器碼的技術&#xff0c;與傳統的 JIT&#xff08;Just-In-Time Compilation&#xff09;編譯方式形成對比。在.NET 中&#xff0c;AOT 編譯可以在應用發布時將 IL&#xff08;中間語言&…

博客系統自動化測試

基于SSM&#xff08;Spring Spring MVC MyBatis&#xff09;框架構建的個人博客系統&#xff0c;通過分層架構實現高效協作&#xff1a;Spring負責依賴注入與事務管理&#xff0c;Spring MVC處理HTTP請求分發&#xff0c;MyBatis完成數據持久化操作。系統包含以下核心功能模塊…

animate.css詳解:輕松實現網頁動畫效果

前言 在網頁設計中&#xff0c;動畫效果不僅僅是視覺上的裝飾&#xff0c;更是提升用戶體驗的重要元素。animate.css 作為一個輕量級的 CSS 動畫庫&#xff0c;提供了豐富的預設動畫效果&#xff0c;本文將探討 animate.css 使用方法以及在實際項目中的應用案例&#xff0c;幫助…

【多智能體】基于嵌套進化算法的多代理工作流

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一個正在變禿、變強的文藝傾年。 &#x1f514;本專欄《人工智能》旨在記錄最新的科研前沿&#xff0c;包括大模型、具身智能、智能體等相關領域&#xff0c;期待與你一同探索、學習、進步&#xff0c;一起卷起來叭&#xff…

電源知多少?LDO VS DCDC((下)

首先補充幾個上一節沒有提到的知識&#xff0c;我們通常說的DCDC同步整流是指什么&#xff1f; 同步是指采用通態電阻極低的專用功率MOS來取代整流二極管以降低整流損耗&#xff0c;&#xff0c;但是同步整流有以下兩點需要注意&#xff1a;1、MOS在導通之后的壓降比較低&…

數組方法_push()/pop()/數組方法_shift()/unshift()

push 方法用于在數組的末端添加一個或多個元素&#xff0c;并返回添加新元 素后的數組長度。注意&#xff0c;該方法會改變原數組 var arr [];arr.push("顫三") // 1arr.push(itbaizhan) // 2arr.push(true, {}) // 4arr // [顫三 , itbaizhan, true, {}] pop 方法用…