設計循環隊列(詳解)

呀哈嘍,我是結衣
今天給大家帶來的內容如標題所述,我們來設計環形隊列,雖然隊列沒有講,但是我就是想講啊。那么環形隊列現在開始。

隊列的屬性

在設計環形隊列前,我們先要了解隊列的特點(先進先出),就想現實中我們排隊一樣,先到的人先得。所以現實中銀行的取票機是可以用隊列實現的。

循環隊列

本次講解是基于leetcode的以題來講解的,貼張圖給大家介紹吧:
在這里插入圖片描述
看完題目不知道大家有沒有思路呢?沒有的話就聽我詳細的解釋吧。

順序表or鏈表

看完題目你最先想到的實現方法是順序表還是鏈表呢?倒不是說這兩種方法只能選擇一個,而是實現難易程度問題,你覺得用順序表難還是用鏈表難呢?這里我選擇用順序表來講解,我覺得順序表簡單一些呢。

順序表實現循環隊列

在實現之前我們來看看題目要我們實現的功能吧:

typedef struct {} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {}bool myCircularQueueDeQueue(MyCircularQueue* obj) {}int myCircularQueueFront(MyCircularQueue* obj) {}int myCircularQueueRear(MyCircularQueue* obj) {}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {}bool myCircularQueueIsFull(MyCircularQueue* obj) {}void myCircularQueueFree(MyCircularQueue* obj) {}

在這里插入圖片描述
了解完要求下面我們就要分析了。

怎樣實現循環

首先我們要定義一個頭和尾。(front和back)他們就是下標哈。
有了頭和尾。我們要把他們的初始值給多少呢,都給‘0’還是給‘-1’呢,這里我的做法是把頭和尾都給‘0’,你可能會說那如果插入了一個數,back怎么辦。哼哼,我們把back++,我們讓back指向的最后一個數的下一個,而非最后一個數,那么新的問題又來了,當出現這種情況怎么辦。
在這里插入圖片描述
back不就出去了嗎,是的,我們要解決這個問題就要多定義一個空間,題目讓我們定義k個空間,我們就要定義k+1個空間。但是有一個空間是不存儲數據的。
在這里插入圖片描述
在k+1個空間中始終有一個空間是不存儲數據的只有這樣才能滿足題目要求的k個空間。
在這里插入圖片描述
這就是循環的示意圖,當前面有空間,又要插入數據時,在back的位置上插入數據后再將back = 0。

結構體的創建

typedef struct {int* data;int front;int back;int k;
} MyCircularQueue;

相信看完上面的簡介這個結構體的創建是沒有問題的吧。

函數的實現

這里的函數的實現并不是按照題目順序來進行的。因為這里的函數也可以相互的調用為后續節省時間。

初始化

MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* tmp = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));tmp->data = (int*)malloc(sizeof(int) * (k + 1));tmp->front = 0;tmp->back = 0;tmp->k = k;return tmp;
}

我們先要malloc一個結構體的空間,然后再malloc tmp->data這個數組的大小,因為我們有一個空位置所以就開了k+1個的空間。還有頭和尾的賦值尾‘0’,在上面的實現循環里有講解。

隊列判空

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {if (obj->back == obj->front){return true;}return false;
}

這個代碼就很直觀了,back == front就直接判空了。因為我們這里的back是不會有數據的,出現這種情況這樣最初的時候在那種情況就是隊列為空的情況。

隊列判滿

bool myCircularQueueIsFull(MyCircularQueue* obj) {if ((obj->back + 1) % (obj->k + 1) == obj->front){return true;}return false;
}

我們都知道當back的下一個為front的時候就是滿的時候,所以寫成back+1 == front是不是就可以了呢?不是不行,多加個判斷就可以了,但是為我們要介紹的方法取余的方法,在這種循環中就特別的好用,利用的就是當被除數比除數小的時候余數為被除數。

數據插入

寫完判空判滿的函數,我們下面就會輕松一些
要插入數據我們首先就是要判斷隊列有沒有滿,如果滿了就不能插入,并且返回false

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if (myCircularQueueIsFull(obj)){return false;}obj->data[obj->back] = value;if (obj->back == obj->k)obj->back = 0;elseobj->back++;return true;
}

除了判滿,我們還要小心當back在最后的情況下,在最后的話如果我們還是back++的話,back就出界了,后果可是很嚴重的,后面返回為數據的時候就可能會訪問野指針。導致程序崩潰。所以我們就要加判斷呢。

數據刪除

刪除數據的時候我們要知道隊列不能為空,為空就不能刪除,返回false。

bool myCircularQueueDeQueue(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return false;}if (obj->front == obj->k)obj->front = 0;elseobj->front++;return true;
}

當然后面判斷和前面插入的時候相似,front在最后的時候就不能++了,要讓他等于0。

返回頭

不能為空

int myCircularQueueFront(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return -1;}return obj->data[obj->front];
}

返回尾

不能為空的同時還要注意,back為0的時候,如果你還 減減 不久變成負數了嗎,這樣肯定是不行的,所以我們要再加一個判斷咯。

int myCircularQueueRear(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return -1;}if (obj->back == 0)return obj->data[obj->k];elsereturn obj->data[obj->back - 1];
}

銷毀

void myCircularQueueFree(MyCircularQueue* obj) {free(obj);obj = NULL;
}

銷毀就是十分的簡單

循環隊列代碼

typedef struct {int* data;int front;int back;int k;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* tmp = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));tmp->data = (int*)malloc(sizeof(int) * (k + 1));tmp->front = 0;tmp->back = 0;tmp->k = k;return tmp;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj) {if (obj->back == obj->front){return true;}return false;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {if ((obj->back + 1) % (obj->k + 1) == obj->front){return true;}return false;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if (myCircularQueueIsFull(obj)){return false;}obj->data[obj->back] = value;if (obj->back == obj->k)obj->back = 0;elseobj->back++;return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return false;}if (obj->front == obj->k)obj->front = 0;elseobj->front++;return true;
}int myCircularQueueFront(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return -1;}return obj->data[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj) {if (myCircularQueueIsEmpty(obj)){return -1;}if (obj->back == 0)return obj->data[obj->k];elsereturn obj->data[obj->back - 1];
}void myCircularQueueFree(MyCircularQueue* obj) {free(obj);obj = NULL;
}


在這里插入圖片描述

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

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

相關文章

鴻蒙(HarmonyOS)應用開發——ArkTs學習準備

介紹 前面我們已經介紹了,如何安裝HarmonyOS的IDE ,那么現在我們來介紹一下。HarmonyOS 開發的語言——ArkTs. ArkTS 是HarmonyOS的開發語言,他是typescript 的擴展,而typesrcipt是javascript的超集,如果你不太熟悉typescript語法…

qml Loader使用介紹

QML Loader 是 Qt Quick 框架中的一個元素,它允許你動態地加載和卸載 QML 組件。Loader 的作用主要體現在以下幾個方面: 延遲加載:Loader 允許你在需要時才加載組件,而不是在應用程序啟動時一次性加載所有組件。這樣可以加快應用程序的啟動時間,因為它只需要初始化用戶當前…

MIT_線性代數筆記:列空間和零空間

目錄 前言子空間綜述列空間 Column space零空間(或化零空間)Nullspaceb 值的影響 Other values of b 前言 本節繼續研究子空間,特別是矩陣的列空間(column space)和零空間(nullspace)。 子空間…

FreeRTOS的并行與并發思考

FreeRTOS的任務觸發是由滴答時鐘觸發SysTick中斷來觸發調度器執行或阻塞或掛起和切換任務的。 首先是任務的并發能力,FreeRTOS的任務執行是基于全搶占調度機制,任務優先級按在就緒列表中由高到低排布,系統首先執行最高優先級任務,…

Django web開發(一) - 前端

文章目錄 前端開發1.快速開發網站2.標簽2.1 編碼2.2 title2.3 標題2.4 div和span2.5 超鏈接2.6 圖片小結標簽的嵌套2.7 列表2.8 表格2.9 input系列2.10 下拉框2.11 多行文本用戶注冊案例: 用戶注冊GET 方式POST 方式表單數據提交優化 3.CSS樣式3.1 快速上手3.2 CSS應用方式1. 在…

Docker run 命令

docker run :創建一個新的容器并運行一個命令 語法 docker run [OPTIONS] IMAGE [COMMAND] [ARG...]OPTIONS說明: -a stdin:指定標準輸入輸出內容類型,可選STDIN/STDOUT/STDERR三項; -d:后臺運行容器&am…

SAP-部分字段變更

在SAP中部分字段是可以自行調整的,例如下圖 這個字段是客戶組1,已經被改成一級經理,現在來操作改回客戶組1 首先選擇字段點擊F1-技術信息-數據元素(雙擊) . . 保存,返回,激活,返…

redis運維(十八)pipeline

一 pipeline 流水線 說明: 這里講解的不是jenkins的pipeline流水線這里pipeline: 管道 redis為什么要提供pipeline功能 事務和pipeline ① pipeline的理念 強調:單純的pipeline跟事務沒有關系redis-cli --pipe --> 使用了pipeline機制說明&a…

排序算法總結

1 排序算法 1.1 快速排序 1.1.1 算法思想 先取一個隨機數,然后和數組的最后一個數交換 進行partition過程,也就是比數組最后一個數小的放在數組左邊,大的放在右邊,相等的在數組中間,最后把數組的最后一個數也要放到中…

【LeetCode刷題-回溯】-- 46.全排列

46.全排列 方法:回溯法 一種通過探索所有可能的候選解來找出所有的解的算法,如果候選解被確認不是一個解,回溯法會通過在上一步進行一些變化拋棄該解,即回溯并且再次嘗試 使用一個標記數組表示已經填過的數 class Solution {pu…

【前端】yarn介紹和使用

yarn介紹和使用 一、什么是yarn?二、安裝yarn三、yarn用法四、yarn更多用法 一、什么是yarn? yarn是快速、可靠、安全的依賴管理。 yarn官網:https://yarn.nodejs.cn/ Yarn 是代碼的包管理器。 它允許你與世界各地的其他開發者使用和共享&am…

如何設置實現本地JumpServer遠程訪問管理界面

文章目錄 前言1. 安裝Jump server2. 本地訪問jump server3. 安裝 cpolar內網穿透軟件4. 配置Jump server公網訪問地址5. 公網遠程訪問Jump server6. 固定Jump server公網地址 前言 JumpServer 是廣受歡迎的開源堡壘機,是符合 4A 規范的專業運維安全審計系統。JumpS…

C語言for循環結構經典練習

文章目錄 一、for循環基本知識二、經典例題及解析1.水仙花數2.求規定范圍內的完數3.求規定范圍內質數4.計算階乘之和5.計算55555555555555(類型)6.計算112123123412345(類型)7.判斷用戶輸入正整數的位數8.判斷某正整數是否為回文數9.九九乘法表10.統計用戶輸入的字符中&#xf…

PTA 公路村村通

現有村落間道路的統計數據表中,列出了有可能建設成標準公路的若干條道路的成本,求使每個村落都有公路連通所需要的最低成本。 輸入格式: 輸入數據包括城鎮數目正整數N(≤1000)和候選道路數目M(≤3N)&…

JVM 之 javac、java、javap 命令詳解

目錄 一. 前言 二. javac 命令 三. java 命令 四. javap 命令 一. 前言 在日常工作中,我們新建 Java工程,寫好代碼后,編譯和運行幾乎都是通過 IDE(如idea、eclipse)工具完成。但作為 Java開發者還是要了解下 Java虛…

Modbus RTU協議及modbus庫函數使用

一、與Modbus TCP的區別 在一般工業場景使用modbus RTU的場景還是更多一些,modbus RTU基于串行協議進行收發數據,包括RS232/485等工業總線協議。 與modbus TCP不同的是RTU沒有報文頭MBAP字段,但是在尾部增加了兩個CRC檢驗字節(CRC…

Android之在RecyclerView列表中實現單選

一、實現效果 單選、可取消選中、列表數據可更新(選擇狀態清空,可重新選擇) RecyclerView列表單選 二、實現步驟 僅展示部分核心代碼,請主要參考適配器的定義 1、Item布局 selected_tip_list_item.xml文件 包含一個TextView和…

Spring Boot集成MyBatis實現多數據源訪問的“秘密”

文章目錄 為什么需要多數據源?Spring Boot集成MyBatis的基礎配置使用多數據源小結 🎉Spring Boot集成MyBatis實現多數據源訪問的“秘密” ☆* o(≧▽≦)o *☆嗨~我是IT陳寒🍹?博客主頁:IT陳寒的博客🎈該系列文章專欄&…

力扣:178. 分數排名(Python3)

題目: 表: Scores ---------------------- | Column Name | Type | ---------------------- | id | int | | score | decimal | ---------------------- 在 SQL 中,id 是該表的主鍵。 該表的每一行都包含了一場比賽的分數。Score …