【10.2】隊列-設計循環隊列

一、題目

????????設計你的循環隊列實現。 循環隊列是一種線性數據結構,其操作表現基于 FIFO(先進先出)原則并且隊尾被連接在隊首之后以形成一個循環。它也被稱為“環形緩沖器”。

????????循環隊列的一個好處是我們可以利用這個隊列之前用過的空間。在一個普通隊列里,一旦一個隊列滿了,我們就不能插入下一個元素,即使在隊列前面仍有空間。但是使用循環隊列,我們能使用這些空間去存儲新的值。

你的實現應該支持如下操作:

  • MyCircularQueue(k): 構造器,設置隊列長度為 k 。
  • Front: 從隊首獲取元素。如果隊列為空,返回 -1 。
  • Rear: 獲取隊尾元素。如果隊列為空,返回 -1 。
  • enQueue(value): 向循環隊列插入一個元素。如果成功插入則返回真。
  • deQueue(): 從循環隊列中刪除一個元素。如果成功刪除則返回真。
  • isEmpty(): 檢查循環隊列是否為空。
  • isFull(): 檢查循環隊列是否已滿。

示例:

MyCircularQueue circularQueue = new MyCircularQueue(3); // 設置長度為 3
circularQueue.enQueue(1); ?// 返回 true
circularQueue.enQueue(2); ?// 返回 true
circularQueue.enQueue(3); ?// 返回 true
circularQueue.enQueue(4); ?// 返回 false,隊列已滿
circularQueue.Rear(); ?// 返回 3
circularQueue.isFull(); ?// 返回 true
circularQueue.deQueue(); ?// 返回 true
circularQueue.enQueue(4); ?// 返回 true
circularQueue.Rear(); ?// 返回 4

提示:

  • 所有的值都在 0?至 1000 的范圍內;
  • 操作數將在 1 至 1000 的范圍內;
  • 請不要使用內置的隊列庫。

二、解題思路

2.1 數組實現

????????我們可以通過數組來模擬循環隊列,利用數組的索引構建一個虛擬的環形結構。在循環隊列中,設置兩個指針:隊尾 `rear` 和隊首 `front`,隊列的大小是固定的。結構如下圖所示:

????????在循環隊列中,當隊列為空時,`front` 和 `rear` 相等,即 `front == rear`;而當隊列的所有空間都被占滿時,同樣會出現 `front == rear` 的情況。為了區分這兩種狀態,我們規定隊列的數組容量為 `capacity`,但循環隊列最多只能存儲 `capacity - 1` 個元素。當隊列中只剩下一個空閑的存儲單元時,就認為隊列已滿。因此,隊列判空的條件是 `front == rear`,而判滿的條件是 `front == (rear + 1) % capacity`。

????????對于一個固定大小的數組,只要知道隊尾 `rear` 和隊首 `front`,就可以計算出隊列的當前長度:? (rear - front + capacity) mod capacity

循環隊列的主要屬性如下:

????????**`elements`**:一個固定大小的數組,用于存儲循環隊列的元素。
????????**`capacity`**:循環隊列的容量,即隊列中最多可以容納的元素數量。
????????**`front`**:隊首元素在數組中的索引。
????????**`rear`**:隊尾元素的下一個位置的索引。

循環隊列的接口方法如下:

????????**`MyCircularQueue(int k)`**:初始化隊列,數組的空間大小為 `k + 1`,并將 `front` 和 `rear` 初始化為 0。
????????**`enQueue(int value)`**:在隊列的尾部插入一個元素,并將 `rear` 更新為 `(rear + 1) % capacity`。
????????**`deQueue()`**:從隊首取出一個元素,并將 `front` 更新為 `(front + 1) % capacity`。
????????**`Front()`**:返回隊首的元素,需要先檢測隊列是否為空。
????????**`Rear()`**:返回隊尾的元素,需要先檢測隊列是否為空。
????????**`isEmpty()`**:檢測隊列是否為空,只需判斷 `rear` 是否等于 `front`。
????????**`isFull()`**:檢測隊列是否已滿,只需判斷 `front` 是否等于 `(rear + 1) % capacity`。

????????通過這種方式,循環隊列能夠高效地利用數組空間,同時避免普通隊列在空間利用上的不足。

#include <iostream>
#include <vector>
using namespace std;class MyCircularQueue {
private:int front;           // 隊首指針int rear;            // 隊尾指針int capacity;        // 隊列容量vector<int> elements; // 用于存儲隊列元素的數組public:// 構造函數,初始化隊列MyCircularQueue(int k) {this->capacity = k + 1;          // 容量為 k + 1,多分配一個空間用于區分空和滿狀態this->elements = vector<int>(capacity); // 初始化數組rear = front = 0;                // 初始化隊首和隊尾指針}// 向循環隊列插入一個元素bool enQueue(int value) {if (isFull()) {return false; // 隊列已滿,插入失敗}elements[rear] = value;         // 將元素插入隊尾rear = (rear + 1) % capacity;   // 更新隊尾指針(循環)return true;}// 從循環隊列中刪除一個元素bool deQueue() {if (isEmpty()) {return false; // 隊列為空,刪除失敗}front = (front + 1) % capacity; // 更新隊首指針(循環)return true;}// 獲取隊首元素int Front() {if (isEmpty()) {return -1; // 隊列為空,返回 -1}return elements[front]; // 返回隊首元素}// 獲取隊尾元素int Rear() {if (isEmpty()) {return -1; // 隊列為空,返回 -1}return elements[(rear - 1 + capacity) % capacity]; // 返回隊尾元素(處理循環情況)}// 檢查隊列是否為空bool isEmpty() {return rear == front; // 隊首和隊尾指針相等時,隊列為空}// 檢查隊列是否已滿bool isFull() {return ((rear + 1) % capacity) == front; // 隊尾的下一個位置是隊首時,隊列已滿}
};int main() {// 創建循環隊列,容量為 3MyCircularQueue circularQueue(3);// 測試 enQueue 操作cout << "enQueue(1): " << circularQueue.enQueue(1) << endl; // 輸出: 1 (true)cout << "enQueue(2): " << circularQueue.enQueue(2) << endl; // 輸出: 1 (true)cout << "enQueue(3): " << circularQueue.enQueue(3) << endl; // 輸出: 1 (true)cout << "enQueue(4): " << circularQueue.enQueue(4) << endl; // 輸出: 0 (false,隊列已滿)// 測試 Rear 操作cout << "Rear(): " << circularQueue.Rear() << endl; // 輸出: 3// 測試 isFull 操作cout << "isFull(): " << circularQueue.isFull() << endl; // 輸出: 1 (true)// 測試 deQueue 操作cout << "deQueue(): " << circularQueue.deQueue() << endl; // 輸出: 1 (true)// 測試 enQueue 操作cout << "enQueue(4): " << circularQueue.enQueue(4) << endl; // 輸出: 1 (true)// 測試 Rear 操作cout << "Rear(): " << circularQueue.Rear() << endl; // 輸出: 4// 測試 Front 操作cout << "Front(): " << circularQueue.Front() << endl; // 輸出: 2// 測試 isEmpty 操作cout << "isEmpty(): " << circularQueue.isEmpty() << endl; // 輸出: 0 (false)return 0;
}

復雜度分析

  • 時間復雜度:初始化和每項操作的時間復雜度均為?O(1)。

  • 空間復雜度:O(k),其中?k?為給定的隊列元素數目。

?

2.2 鏈表實現

????????我們也可以使用鏈表來實現隊列。與數組相比,鏈表實現隊列更加靈活,因為鏈表可以在 O(1)時間復雜度內完成元素的插入和刪除操作。具體來說,入隊操作是將新元素插入到鏈表的尾部,而出隊操作則是返回鏈表的頭節點,并將頭節點指向下一個節點。

循環隊列的屬性如下:

  • head:鏈表的頭節點,表示隊列的頭部。

  • tail:鏈表的尾節點,表示隊列的尾部。

  • capacity:隊列的容量,即隊列可以存儲的最大元素數量。

  • size:隊列當前存儲的元素數量。

????????通過鏈表實現循環隊列,可以避免數組實現中需要處理索引循環的問題,同時也能高效地完成隊列的基本操作。

#include <iostream>
using namespace std;// 鏈表節點定義
struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(nullptr) {}
};class MyCircularQueue {
private:ListNode *head;  // 隊首指針,指向鏈表的頭節點ListNode *tail;  // 隊尾指針,指向鏈表的尾節點int capacity;    // 隊列的容量int size;        // 隊列當前的大小public:// 構造函數,初始化隊列MyCircularQueue(int k) {this->capacity = k;  // 設置隊列容量this->size = 0;      // 初始化隊列大小為 0this->head = nullptr; // 初始化隊首指針為空this->tail = nullptr; // 初始化隊尾指針為空}// 向隊列尾部插入一個元素bool enQueue(int value) {if (isFull()) {return false; // 隊列已滿,插入失敗}ListNode *node = new ListNode(value); // 創建新節點if (!head) {head = tail = node; // 如果隊列為空,新節點既是隊首也是隊尾} else {tail->next = node; // 將新節點鏈接到隊尾tail = node;       // 更新隊尾指針}size++; // 隊列大小加 1return true;}// 從隊列頭部刪除一個元素bool deQueue() {if (isEmpty()) {return false; // 隊列為空,刪除失敗}ListNode *node = head; // 保存隊首節點head = head->next;     // 更新隊首指針size--;                // 隊列大小減 1delete node;           // 釋放隊首節點的內存if (isEmpty()) {tail = nullptr; // 如果隊列為空,更新隊尾指針為空}return true;}// 獲取隊首元素int Front() {if (isEmpty()) {return -1; // 隊列為空,返回 -1}return head->val; // 返回隊首節點的值}// 獲取隊尾元素int Rear() {if (isEmpty()) {return -1; // 隊列為空,返回 -1}return tail->val; // 返回隊尾節點的值}// 檢查隊列是否為空bool isEmpty() {return size == 0; // 隊列大小為 0 時為空}// 檢查隊列是否已滿bool isFull() {return size == capacity; // 隊列大小等于容量時為滿}
};int main() {// 創建循環隊列,容量為 3MyCircularQueue circularQueue(3);// 測試 enQueue 操作cout << "enQueue(1): " << circularQueue.enQueue(1) << endl; // 輸出: 1 (true)cout << "enQueue(2): " << circularQueue.enQueue(2) << endl; // 輸出: 1 (true)cout << "enQueue(3): " << circularQueue.enQueue(3) << endl; // 輸出: 1 (true)cout << "enQueue(4): " << circularQueue.enQueue(4) << endl; // 輸出: 0 (false,隊列已滿)// 測試 Rear 操作cout << "Rear(): " << circularQueue.Rear() << endl; // 輸出: 3// 測試 isFull 操作cout << "isFull(): " << circularQueue.isFull() << endl; // 輸出: 1 (true)// 測試 deQueue 操作cout << "deQueue(): " << circularQueue.deQueue() << endl; // 輸出: 1 (true)// 測試 enQueue 操作cout << "enQueue(4): " << circularQueue.enQueue(4) << endl; // 輸出: 1 (true)// 測試 Rear 操作cout << "Rear(): " << circularQueue.Rear() << endl; // 輸出: 4// 測試 Front 操作cout << "Front(): " << circularQueue.Front() << endl; // 輸出: 2// 測試 isEmpty 操作cout << "isEmpty(): " << circularQueue.isEmpty() << endl; // 輸出: 0 (false)return 0;
}

復雜度分析

  • 時間復雜度:初始化和每項操作的時間復雜度均為?O(1)。

  • 空間復雜度:O(k),其中?k?為給定的隊列元素數目。

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

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

相關文章

博客之星2024年度總評選——我的年度創作回顧與總結

2024年&#xff0c;是我在CSDN博客上持續耕耘、不斷成長的一年。在此&#xff0c;與大家分享一下我的年度創作回顧與總結。 一、創作成長與突破 在人工智能領域&#xff0c;技術迭代迅速&#xff0c;知識更新頻繁。為了保持自己的競爭力&#xff0c;在今年&#xff0c;我始終…

IDEA運行Java項目總會報程序包xxx不存在

我的在另外一臺電腦上跑是沒有問題的&#xff0c;在新的電腦上跑的時候&#xff0c;又出現了這個惡心的問題...... 思來想去&#xff0c;唯一的問題就是我的mavn環境沒的配置好 如何在本地部署mavn環境&#xff0c;這里推薦一篇很好的文章&#xff1a; Maven安裝與配置&…

java 根據前端傳回的png圖片數組,后端加水印加密碼生成pdf,返回給前端

前端傳回的png圖片數組&#xff0c;后端加水印加密碼生成pdf&#xff0c;返回給前端 場景&#xff1a;重點&#xff1a;maven依賴controllerservice 場景&#xff1a; 當前需求&#xff0c;前端通過html2canvas將頁面報表生成圖片下載&#xff0c;可以仍然不滿意。 需要java后…

數據分庫分表和遷移方案

在我們業務快速發展的過程中&#xff0c;數據量必然也會迎來突飛猛漲。那么當我們的數據量百倍、千倍、萬倍、億倍增長后&#xff0c;原有的單表性能就不能滿足我們日常的查詢和寫入了&#xff0c;此時數據架構就不得不進行拆分&#xff0c;比如單表拆分成10張表、100張表、單個…

線上突發:MySQL 自增 ID 用完,怎么辦?

線上突發&#xff1a;MySQL 自增 ID 用完&#xff0c;怎么辦&#xff1f; 1. 問題背景2. 場景復現3. 自增id用完怎么辦&#xff1f;4. 總結 1. 問題背景 最近&#xff0c;我們在數據庫巡檢的時候發現了一個問題&#xff1a;線上的地址表自增主鍵用的是int類型。隨著業務越做越…

[Java] Solon 框架的三大核心組件之一插件擴展體系

1、Solon 的三大核心組件 核心組件說明Plugin 插件擴展機制提供“編碼風格”的擴展體系Ioc/Aop 應用容器提供基于注入依賴的自動裝配體系ContextHandler 通用上下文處理接口提供“開放式處理”適配體系&#xff08;俗稱&#xff0c;三元合一&#xff09; 2、Solon Plugin 插件…

TRELLIS微軟的圖生3D

TRELLIS 教程目錄&#xff1a; Youtube&#xff1a;https://www.youtube.com/watch?vJqFHZ-dRMhI 官網地址&#xff1a;https://trellis3d.github.io/ GitHub&#xff1a;https://github.com/Microsoft/TRELLIS 部署目錄&#xff1a; 克隆項目 git clone --recurse-submodul…

Java導出通過Word模板導出docx文件并通過QQ郵箱發送

一、創建Word模板 {{company}}{{Date}}服務器運行情況報告一、服務器&#xff1a;總告警次數&#xff1a;{{ServerTotal}} 服務器IP:{{IPA}}&#xff0c;總共告警次數:{{ServerATotal}} 服務器IP:{{IPB}}&#xff0c;總共告警次數:{{ServerBTotal}} 服務器IP:{{IPC}}&#x…

【22】Word:小李-高新技術企業政策?

目錄 題目? NO1.2 NO3 NO4 NO5.6 NO7.8 NO9.10 若文章中存在刪除空白行等要求&#xff0c;可以到最后來完成。注意最后一定要檢查此部分&#xff01;注意&#xff1a;大多是和事例一樣即可&#xff0c;不用一摸一樣&#xff0c;但也不要差太多。 題目 NO1.2 F12Fn&a…

自動化部署(三):項目管理平臺

一、項目管理平臺作用 幫助團隊高效規劃、執行和監控項目進度&#xff0c;確保任務按時完成并實現目標 敏捷開發&#xff1a;提供標準敏捷研發管理&#xff0c;支持Scrum 與 Kanban 規模化敏捷&#xff1a;支持大型研發團隊跨項目協同&#xff0c;實現多項目路線圖規劃和資源管…

常用集合-數據結構-MySql

目錄 java核心&#xff1a; 常用集合與數據結構: 單例集合: 雙列集合: 線程安全的集合: ConcurrentHashMap集合: HashTable集合: CopyOnWriteArrayList集合: CopyOnWriteArraySet集合: ConcurrentLinkedQueue隊列: ConcurrentSkipListMap和ConcurrentSkipListSet&…

IP屬地與視頻定位位置不一致:現象解析與影響探討

在數字化時代&#xff0c;IP屬地和視頻定位位置已成為我們獲取網絡信息、判斷內容真實性的重要依據。然而&#xff0c;有時我們會發現&#xff0c;某些視頻內容中展示的定位位置與其發布者的IP屬地并不一致。這種不一致現象引發了廣泛的關注和討論。本文旨在深入剖析IP屬地與視…

計算機畢業設計hadoop+spark股票基金推薦系統 股票基金預測系統 股票基金可視化系統 股票基金數據分析 股票基金大數據 股票基金爬蟲

溫馨提示&#xff1a;文末有 CSDN 平臺官方提供的學長聯系方式的名片&#xff01; 溫馨提示&#xff1a;文末有 CSDN 平臺官方提供的學長聯系方式的名片&#xff01; 溫馨提示&#xff1a;文末有 CSDN 平臺官方提供的學長聯系方式的名片&#xff01; 作者簡介&#xff1a;Java領…

機器學習-數據集劃分

文章目錄 一. 為什么要劃分數據集二. 數據集劃分的方法1. 留出法&#xff1a;2. 交叉驗證&#xff1a;將數據集劃分為訓練集&#xff0c;驗證集&#xff0c;測試集3. 留一法&#xff1a;4. 自助法&#xff1a; 一. 為什么要劃分數據集 為了能夠評估模型的泛化能力&#xff0c;可…

根據當前用戶的活動、當地天氣和喜歡音樂類型,然后根據這些信息來播放相應的Spotify音樂 附python代碼

這段代碼是一個Python腳本,它使用了幾個外部庫來創建一個簡單的圖形用戶界面(GUI),讓用戶根據當前用戶的活動、當地天氣和喜歡音樂類型,然后根據這些信息來播放相應的音樂。 1. **導入庫**: - `openai`:用于與OpenAI API交互(盡管在這段代碼中沒有使用)。 - `sp…

excel導入數據處理前端

dialogErrorVisible false;dialogErrorTitle ;//錯誤標題public get gridErrorOptions(): GridOptions {return {headerHeight: 30, // 表頭高度rowHeight: 30, // 行高columnDefs: [//列定義{headerName: "序號",field: "SerialNumber",width: 40,pinne…

Vue 攔截監聽原理

Vue 漸進式JavaScript 框架 學習筆記 - Vue 攔截監聽原理 目錄 攔截監聽原理 如何跟蹤變化 攔截監聽示例 觀察者 注意:vue3的變化 總結 攔截監聽原理 如何跟蹤變化 當你把一個普通的Javascript 對象傳入 Vue 實例作為data選項&#xff0c;Vue 將遍歷此對象所有的proper…

全面評測 DOCA 開發環境下的 DPU:性能表現、機器學習與金融高頻交易下的計算能力分析

本文介紹了我在 DOCA 開發環境下對 DPU 進行測評和計算能力測試的一些真實體驗和記錄。在測評過程中&#xff0c;我主要關注了 DPU 在高并發數據傳輸和深度學習場景下的表現&#xff0c;以及基本的系統性能指標&#xff0c;包括 CPU 計算、內存帶寬、多線程/多進程能力和 I/O 性…

基于JAVA的校園二手商品交易平臺的設計與開發

摘 要&#xff1a;政府政策引導與社會觀念的轉變使得國內大學生的創業意識逐漸提高&#xff0c;很多高校大學生開始自主創業。目前我國各大高校暫且還沒有較為成型的針對校內學生創業者的校園網絡服務平臺。本文首先主要是介紹了關于java語言以及web開發的相關技術&#xff0c;…

HarmonyOS Next 應用UI生成工具介紹

背景 HarmonyOS Next適配開發過程中難買難要參考之前邏輯&#xff0c;但是可能時間較長文檔不全&#xff0c;只能參考Android或iOS代碼&#xff0c;有些邏輯較重的場景還可以通過AI工具將Android 的Java代碼邏輯轉成TS完成部分復用。對于一些UI場景只能手動去寫&#xff0c;雖…