循環隊列與循環雙端隊列

文章目錄

  • 前言
  • 循環隊列
  • 循環雙端隊列


前言

1、學習循環隊列和循環雙端隊列能加深我們對隊列的理解,提高我們的編程能力。
2、本文循環隊列使用的是數組,循環雙端隊列用的是雙向鏈表
3、題目連接:設計循環隊列 ,設計循環雙端隊列。

循環隊列

1、什么是循環隊列?

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

在這里插入圖片描述

2、實現的功能

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

3、設計
有兩種方案:a:利用數組來存儲數據,b:利用鏈表來存儲數據
我們這里使用數組的方式
(1)我們設置一個頭指針,和一個尾指針(指的時最后一個有數據位置的下一個位置,為什么不直接指向最后有數據那個位置呢?因為這樣能更好的判斷隊列是否為空和隊列是否已經滿的情況),頭指針(front),尾指針(rear),容量(k)。

(2) 為了解決尾指針指向最后一個數據后一個的問題,我們可以多申請一個空間,就不會使尾指針指的位置超出數組了,這個問題也叫假溢出。

(3)判斷空,當front=rear時為空
![在這里插入圖片描述](https://img-blog.csdnimg.cn/direct/d05483fe9eb840fdad065ce02b088b52.png

(4)判斷滿,當 front=(rear+1)%(k+1) 為空

![在這里插入圖片描述](https://img-blog.csdnimg.cn/direct/d06eadb22f7048aa8ede33702d1e9548.png

(5)刪除隊頭元素,使front=(front+1)%(k+1)即可, 也可以通過判斷front是否在(k+1)的位置,在的話就使front=0,不在的話front=front+1即可

![在這里插入圖片描述](https://img-blog.csdnimg.cn/direct/14aff520fd254a0a9b2751cf622e4a82.png

(6)進隊,將數據放到數組下標rear位置上,然后使 rear=(rear+1)%(k+1) 即可,原理同上。

(7)獲取隊頭元素,直接返回隊頭下標的位置的數據即可

(8)獲取隊尾元素,返回 (rear-1+k+1)%(k+1) 位置的數據即可,也可以判斷rear是不是在0的位置,在的話top=k,不在0的位置的話就top=rear-1
![在這里插入圖片描述](https://img-blog.csdnimg.cn/direct/fad58d936d8b45a0b6b65024f18fd026.png

4、代碼實現:

//隊列結構體
typedef struct {//儲存數據int *arr;//頭int front;//指向尾的下一個int rear;//大小int k;
} MyCircularQueue;//初始化循環隊列
MyCircularQueue* myCircularQueueCreate(int k) {//隊列MyCircularQueue* obj=( MyCircularQueue*)malloc(sizeof(MyCircularQueue));//初始化成員obj->arr=(int*)malloc(sizeof(int)*(k+1));obj->front=0;obj->rear=0;obj->k=k;return obj;
}//是否為空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {//當隊頭的下標等于隊尾的下標時隊列為空return obj->front==obj->rear;
}//是否為滿
bool myCircularQueueIsFull(MyCircularQueue* obj) {//當隊頭的下標等于隊尾加一模上k+1時隊列滿了return obj->front==(obj->rear+1)%(obj->k+1);
}//入隊
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//當隊列滿了就返回falseif(myCircularQueueIsFull(obj))return false;//放到rear位置上obj->arr[obj->rear]=value;//這樣當rear+1==k+1時,讓rear回到0這個位置上obj->rear=(obj->rear+1)%(obj->k+1);return true;
}//出隊
bool myCircularQueueDeQueue(MyCircularQueue* obj) {//空時返回falseif(myCircularQueueIsEmpty(obj))return false;//隊頭下標加1,莫上k+1當front+1==k+1時能回到0那個位置obj->front=(obj->front+1)%(obj->k+1);return true;
}//查看頭元素
int myCircularQueueFront(MyCircularQueue* obj) {//空時返回-1if(myCircularQueueIsEmpty(obj))return -1;//直接展示front位置即可int tmp=obj->arr[obj->front];return tmp;
}//查看隊尾元素
int myCircularQueueRear(MyCircularQueue* obj) {//空時返回-1if(myCircularQueueIsEmpty(obj))return -1;//因為返回的是rear-1位置上的數據,當rear>0時,查看的位置時rear-1,當rear=0時就是查看k位置的數據了int tmp=obj->arr[(obj->rear-1+obj->k+1)%(obj->k+1)];return tmp;}//釋放
void myCircularQueueFree(MyCircularQueue* obj) {free(obj->arr);free(obj);
}

循環雙端隊列

1、循環雙端隊列就是在循環隊列的基礎上增加了一些接口,如:可以進行隊頭的插入,進行尾部的刪除。

2、實現的功能接口:

實現 MyCircularDeque 類:

(1)MyCircularDeque(int k) :構造函數,雙端隊列最大為 k 。

(2)boolean insertFront():將一個元素添加到雙端隊列頭部。 如果操作成功返回 true ,否則返回 false 。

(3)boolean insertLast() :將一個元素添加到雙端隊列尾部。如果操作成功返回 true ,否則返回 false 。

(4)boolean deleteFront() :從雙端隊列頭部刪除一個元素。 如果操作成功返回 true ,否則返回 false 。

(5)boolean deleteLast() :從雙端隊列尾部刪除一個元素。如果操作成功返回 true ,否則返回 false 。

(6)int getFront() ):從雙端隊列頭部獲得一個元素。如果雙端隊列為空,返回 -1 。

(7)int getRear() :獲得雙端隊列的最后一個元素。 如果雙端隊列為空,返回 -1 。
(8) boolean isEmpty() :若雙端隊列為空,則返回 true ,否則返回 false 。

(9)boolean isFull() :若雙端隊列滿了,則返回 true ,否則返回 false 。

3、設計
(1)用雙向鏈表的節點,這樣方便找到尾部的上一個節點,利于隊尾的刪除。
(2)定義size來判斷空和滿,再定義兩個節點指針,分別指向隊頭(front)隊尾(rear)容量(k)前驅指針(next)后驅指針(next1)
(3)判斷為空,當size=0時為空。
(4)判斷是否滿,當size=k時為滿。
(5)隊頭插入數據,申請一個節點tmp,再將tmp和front連起來,最后front=tmp即可

在這里插入圖片描述

(6)隊尾插入數據,申請一個節點tmp,再將tmp和rear連接起來,最后rear=tmp即可
在這里插入圖片描述

(7)隊頭刪除,先保存隊頭的后一個節點next,再將front釋放,最后將front=next并把front->next1=NULL即可,注意順序不能亂。

在這里插入圖片描述

(8)隊尾刪除,先保存前一個節點next1,再將rear釋放,最后將rear=next1并把rear->next=NULL即可,注意順序不能亂。

在這里插入圖片描述

(9)獲取隊頭元素,直接返回front的數據即可。
(10)獲取隊尾元素,直接返回rear的數據即可。

4、代碼實現:

//雙向鏈表的結構體
typedef struct  ls
{//前驅struct ls *next;//后驅struct ls *next1;//數據int val;
}ls;class MyCircularDeque {
public://初始化MyCircularDeque(int k) {//容量this->k=k;//大小this->size=0;this->rear=NULL;this->front=NULL;}//隊頭插入數據bool insertFront(int value) {//  滿了,就返回if(isFull())return false;//沒滿//申請一個節點ls *tmp(ls*)malloc(sizeof(ls));tmp->next=NULL;tmp->next1=NULL;tmp->val=value;//空的話頭和尾指向第一個節點if(front==NULL){front=rear=tmp;}//不空,插入頭else{front->next1=tmp;tmp->next=front;front=tmp;}//大小加1size++;return true;}//隊尾插入數據bool insertLast(int value) {if(isFull())return false;//申請節點ls *tmp=(ls*)malloc(sizeof(ls));tmp->next=NULL;tmp->next1=NULL;tmp->val=value;if(rear==NULL){front=rear=tmp;}//尾插到rear后面else{tmp->next1=rear;rear->next=tmp;rear=tmp;}//大小加1size++;return true;}//刪隊頭   bool deleteFront() {//為空if(isEmpty())return false;//只有一個元素ls *tmp=front->next;free(front);if(tmp==NULL)front=rear=tmp;//多個元素else{front=tmp;front->next1=NULL;}//大小-1     size--;return true;}//刪隊尾bool deleteLast() {if(isEmpty())return false;//只有一個元素ls *tmp=rear->next1;free(rear);if(tmp==NULL){rear=front=tmp;}else{tmp->next=NULL;rear=tmp;}// 大小-1size--;return true;}//顯示頭元素int getFront() {//為空if(isEmpty())return -1;//直接返回頭節點的數據return front->val;}//顯示尾節點元素int getRear() {//為空if(isEmpty())return -1;//直接返回尾節點數據return rear->val;}//判斷是否為空bool isEmpty() {//當size==0是為空return size==0;}//判斷是否為滿bool isFull() {//size==k就滿了return size==k;}//釋放鏈表~MyCircularDeque(){ls* tmp=front;while(tmp){ls*p=tmp->next;free(tmp);tmp=p;}}//頭和尾ls* front;ls* rear;//容量和大小int k;int size;
};

以上就是我的分享了

最后,感謝大家的觀看!

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

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

相關文章

【機器學習】有監督學習算法之:支持向量機

支持向量機 1、引言2、決策樹2.1 定義2.2 原理2.3 實現方式2.4 算法公式2.5 代碼示例 3、總結 1、引言 小屌絲:魚哥,泡澡啊。 小魚:不去 小屌絲:… 此話當真? 小魚:此話不假 小屌絲:到底去還是…

Linux 網絡接口的混雜模式(Promiscuous mode)認知

寫在前面 博文內容為 混雜模式的簡單認知理解不足小伙伴幫忙指正 認定一件事,即使拿十分力氣都無法完成,也要拿出十二分力氣去努力。 —《劍來》 網絡接口的混雜模式 混雜模式(Promiscuous mode),簡稱 Promisc mode,俗稱監聽模式…

什么是支持向量機(Support vector machine)和其原理

作為機器學習的基礎算法,SVM被反復提及,西瓜書、wiki都能查到詳細介紹,但是總是覺得還差那么點,于是決定自己總結一下。 一、什么是SVM? 1、解決什么問題? SVM,最原始的版本是用于最簡單的線…

藍橋杯備賽第五篇(動態規劃)

1.數位dp public class Main {static long[] limit;static int length;static long[][] dp;public static long dfs(int pos, int pre, boolean flag, boolean lead) {if (pos length) return 1;if (!flag && !lead && dp[pos][pre] ! -1) return dp[pos][pr…

總結 HashTable, HashMap, ConcurrentHashMap 之間的區別

1.多線程環境使用哈希表 HashMap 不行,線程不安全 更靠譜的,Hashtable,在關鍵方法上加了synchronized 后來標準庫又引入了一個更好的解決方案;ConcurrentHashMap 2.HashMap 首先HashMap本身線程不安全其次HashMap的key值可以為空(當key為空時,哈希會…

【Java數據結構】——五道算法題讓你靈活運用Map和Set

目錄 一.只出現一次的數字 二.寶石與石頭 三.舊鍵盤 四.給定一個數組,統計每個元素出現的次數 五.前K個高頻單詞 一.只出現一次的數字 136. 只出現一次的數字 - 力扣(LeetCode) 算法原理:我們將nums中每個元素都存入到set中…

C/C++嵌入式開發環境搭建,Qt交叉編譯,cmake交叉編譯,clion/vscode遠程開發

目錄 交叉編譯簡介cmake 交叉編譯clion 交叉編譯vscode 遠程嵌入式開發Qt交叉編譯1.安裝交叉編譯工具2.交叉編譯qt庫3.將交叉編譯的Qt庫復制到板子上4.安裝和配置 Qt Creator,支持交叉編譯5.QT嵌入式開發6.QT嵌入式開發報錯解決QIconvCodec::convertToUnicode: usin…

ASUS華碩天選5筆記本電腦FX607JV原裝出廠Win11系統下載

ASUS TUF Gaming F16 FX607JV天選五原廠Windows11系統 適用型號: FX607JU、FX607JI、FX607JV、 FX607JIR、FX607JVR、FX607JUR 下載鏈接:https://pan.baidu.com/s/1l963wqxT0q1Idr98ACzynQ?pwd0d46 提取碼:0d46 原廠系統自帶所有驅動、…

TypeScript中 “ <> “ 語法 和 “ : “ 怎么使用

在 TypeScript 中&#xff0c;尖括號語法(<Type>)和as關鍵字(value as Type)都是用于類型斷言&#xff0c;而冒號(:)用于類型注解。這三種語法在不同的場景下使用&#xff1a; 尖括號語法和as關鍵字&#xff1a; 尖括號語法(<Type>value)&#xff1a; 這種語法在…

[LeetBook]【學習日記】鏈表反轉

來源于「Krahets」的《圖解算法數據結構》 https://leetcode.cn/leetbook/detail/illustration-of-algorithm/ 鏈表反轉的遞歸要點 遞歸終止條件為當前節點為空&#xff0c;表明遍歷到了鏈表尾部遞歸函數傳入參數為當前節點的下一個節點按照是否重新開辟存儲空間分類下面只寫…

python自動化學習--3.8python操作EXCEL文件python日志收集處理

1、Excel文件處理 安裝 openpxl 第三方庫 openpxl 模塊三大組件: 1、工作簿 &#xff08;包含多個sheet工作表&#xff09; 2、工作表 &#xff08;某個數據包含在某個工作表&#xff09; 3、單元格 1、創建excel工作簿 import openpyxl"""Excel表格的創建…

【簡說八股】Spring事務失效可能是哪些原因?

Spring事務介紹 Spring事務是指在Spring框架中對數據庫操作進行管理的一種機制&#xff0c;它確保一組數據庫操作要么完全執行成功&#xff08;提交&#xff09;&#xff0c;要么完全不執行&#xff08;回滾&#xff09;&#xff0c;從而保持數據一致性和完整性。 Spring框架…

GotoXy控制臺光標的位置更新

光標控制解釋 控制臺的光標更新方法, 用于控制數據輸出位置 void gotoXY(int x, int y)//新函數&#xff1a;更新光標 {COORD c;c.X x;c.Y y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); }代碼解釋 這段代碼定義了一個名為 gotoXY 的函數&#xff0c;…

設計模式-裝飾者模式應用實踐

裝飾者模式&#xff08;Decorator Pattern&#xff09;是一種結構型設計模式&#xff0c;它允許動態地向一個現有的對象添加新的功能&#xff0c;同時不改變其結構。這種模式通過創建一個裝飾類來包裝原有的類&#xff0c;提供額外的行為。 下面是一個使用 Java 實現裝飾者模式…

【Spring Boot】實現全局異常處理

1.定義基礎異常接口類 /*** description: 服務接口類* author: MrVK* date: 2021/4/19 21:39*/ public interface BaseErrorInfoInterface {/*** 錯誤碼* return*/String getResultCode();/*** 錯誤描述* return*/String getResultMsg(); } 2.定義錯誤處理枚舉類 /*** desc…

小伙伴詢問AI該怎么學習?本人的一點總結,以思維導圖呈現

如有需要思維導圖的在后臺請留郵箱&#xff0c;相關知識結構目錄 部分導圖

nn.Linear() 使用提醒

原本以為它是和nn.Conv2d()一樣&#xff0c;就看第二個維度的數值&#xff0c;今天才知道&#xff0c;它是只看最后一個維度的數值&#xff01;&#xff01;&#xff01; 例子1 Descripttion: Result: Author: Philo Date: 2024-02-27 14:33:50 LastEditors: Philo LastEditT…

git使用merge命令把dev分支的mian.js文件和src下面的vuex文件夾以及config文件夾單獨合并到master分支上

使用 git merge 命令來單獨合并特定文件或文件夾到另一個分支通常不是最直接的方法&#xff0c;因為 merge 命令是用來合并兩個分支的所有更改的。然而&#xff0c;你可以通過 git cherry-pick 命令或者通過創建臨時補丁&#xff08;patch&#xff09;來實現這一點。 下面是一個…

秒殺的時候怎么使用Redis?

商品信息存儲&#xff1a;在Redis中存儲秒殺商品的庫存信息。可以使用Redis的Hash數據類型&#xff0c;將商品ID作為字段&#xff0c;庫存數量作為值存儲在Hash中。例如&#xff0c;HSET seckill_goods stock_1 100表示商品ID為stock_1的商品庫存數量為100。 秒殺訂單存儲&…

如何使用“Ubuntu 20.04桌面版,安裝MariaDB數據庫“?win10系統?

1、更新軟件包 sudo apt update 2、 安裝MariaDB服務器和客戶端 sudo apt install mariadb-server mariadb-client 3、 查看MeriaDB是否運行 service mysql status :q"退回命令行狀態 4、 設置MariaDB root用戶的密碼 sudo mysql_secure_installation 5、 MariaD…