數據結構1-4 隊列

一、隊列是什么?

先舉一個日常例子,排隊買飯。

排隊買飯

大家按先來后到的順序,在窗口前排隊買飯,先到先得,買完之后走開,輪到下一位買,新來的人排在隊尾,不能插隊。

可見,上面的“隊”的特點是只允許從一端進入,從另一端離開。

這樣的一個隊,放在數據結構中就是“隊列”。

首先,隊列是一個線性表,所以它具有線性表的基本特點。

其次,隊列是一個受限的線性表,受限之處為:只允許從一端進入隊列,從另一端離開。

由此可得:?

? ? ? ? 隊列Queue,是一種操作受限的線性表,只允許在表的一端進行插入,而在表的另一端進行刪除(只允許在隊尾添加元素,在隊頭刪除元素,不支持隨機訪問),向隊列中插入元素稱為入隊或進隊;刪除元素稱為出隊或離隊,FIFO

相關名詞解釋:

  • 入隊:進入隊列,即向隊列中插入元素
  • 出隊:離開隊列,即從隊列中刪除元素
  • 隊頭:允許出隊(刪除)的一端
  • 隊尾:允許入隊(插入)的一端
  • 隊頭元素:隊列中最先入棧的元素
  • 隊尾元素:隊列中最后入棧的元素

二、隊列的實現思路

和棧一樣,隊列也可以有兩種實現方式:數組實現的順序隊列和鏈表實現的鏈隊列。

2.1 隊列的鏈式存儲

2.1.1 原理

? ? ? ? 隊列的鏈式表示稱為鏈隊列,實際是一個同時帶有隊頭指針和隊尾指針的單鏈表。

頭指針指向隊頭結點,尾指針指向隊尾結點,即單鏈表的最后一個結點

以看到,要實現一個鏈隊列,需要以下結構:

1.單鏈表的基本單元結點 —— QueueNode

  • 存儲數據的數據域 —— data
  • 指向下一個結點的指針域 —— next

2.指向鏈表的頭指針 —— head

3.標識隊頭端的隊頭指針 —— front

4.標識隊尾端的隊尾指針 —— rear

其中,頭指針 head 和隊頭指針 front 都指向了單鏈表的第一個結點,所以這個指針可以合二為一,隊頭指針即頭指針。

如此一來,我們可以借助鏈表的尾插法實現隊列的入隊操作,借助鏈表的頭刪法實現隊列的出隊操作。

?可參考動畫版:Linked List Queue Visualization

鏈隊列入隊出隊動畫

2.1.2 隊列的狀態

【空隊列】:空隊列中沒有元素,此時,隊頭下標和隊尾下標均為 0,即front = rear = 0:?

【非空非滿隊列】:隊列不是空隊列且有剩余空間:

【滿隊列】:順序隊列分配的固定空間用盡,沒有多余空間,不能再插入元素,此時 front = 0,rear = MAXSIZE:

2.1.3?代碼實現

typedef int Elemtype;
typedef struct LinkNode {Elemtype data;struct LinkNode *next;
}LinkNode;//先進先出
typedef struct {LinkNode *front, *rear;
}LinkQueue;
2.1.3.1 初始化隊列
//隊列的初始化,使用的是帶頭節點的鏈表
void init_queue(LinkQueue &Q) {Q.front = Q.rear=(LinkNode*)malloc(sizeof(LinkNode));Q.front->next =NULL;}
2.1.3.2 入隊
//入隊
void enqueue(LinkQueue &Q, Elemtype m) {LinkNode *pnew = (LinkNode *)malloc(sizeof(LinkNode));pnew->data = m;pnew->next =NULL;//要讓next 為nullQ.rear->next = pnew;//尾指針next指向pnew,尾插法Q.rear =pnew;//rear指向新的尾部}
2.1.3.3 出隊
bool dequeue(LinkQueue &Q, Elemtype &m) {if (Q.front ==Q.rear) {//隊列為空return false;}LinkNode *q=Q.front->next;//拿到第一個節點,存入qQ.front->next = q->next;讓節點斷鏈m = q->data;if (Q.rear ==q) {Q.rear = Q.front;//鏈表只剩一個節點時,被刪除后要改變rear}free(q);
return true;}
2.1.3.4 主函數
int main() {LinkQueue Q;init_queue(Q);enqueue(Q, 3);enqueue(Q, 4);//   enqueue(Q, 5);Elemtype elem;bool ret;ret = dequeue(Q,elem);if (ret) {printf("dequeue success ele=%d\n",elem);}else {printf("dequeue failed\n");}ret = dequeue(Q,elem);if (ret) {printf("dequeue success ele=%d\n",elem);}else {printf("dequeue failed\n");}ret = dequeue(Q,elem);if (ret) {printf("dequeue success ele=%d\n",elem);}else {printf("dequeue failed\n");}return 0;
}

三、循環隊列

3.1 原理

將這種順序隊列畫成一個圓:

循環隊列的 rear 和 front 能夠在隊列中一圈一圈地轉,像鐘表的時針和分針一樣。?

【空隊列】:隊列中沒有元素,空隊列的條件 ?front = rear?

【滿隊列】:少用一個元素,rear + 1 = front

【歸零法】:就像鐘表的時針滿 12 歸零一樣,front 和 rear 也應該滿某個數后歸零,這個數就是 MAXSIZE。

比如 rear = 6 時,如果按平常做法來 ,下一步應該是 rear = 7,但在這里,我們讓其歸零,所以下一步應該是 rear = 0。

用數學公式來表示上面的歸零過程就是:rear % MAXSIZE

所以滿隊列的判斷條件應該為:(rear + 1) % MAXSIZE = front。

3.2 循環隊列的數組實現

3.2.1 定義

typedef int ElementType;
typedef struct {ElementType data[MaxSize];int front, rear;//隊列頭,隊列尾
}SqQueue;

3.2.2 ?初始化循環隊列

void init_queue(SqQueue &Q) {Q.front =Q.rear = 0;//初始化循環隊列,讓頭尾都指向零號}

3.3.3 判斷空隊

bool is_empty(SqQueue Q) {return Q.front==Q.rear;}

3.3.4 入隊

//入隊
bool enqueue(SqQueue &Q,ElementType m ) {//判斷循環隊列是否滿?if ((Q.rear +1) % MaxSize == Q.front){return  false;}Q.data[Q.rear]=m;Q.rear=(Q.rear + 1)%MaxSize;//rear +1 ,如果大于數組最大下標需要回到開頭return  true;
}

3.3.5 出隊

bool dequeue(SqQueue &Q, ElementType &m) {if (Q.front == Q.rear) {return  false;}m = Q.data[Q.front];Q.front = (Q.front + 1) %MaxSize;return true;}

3.3.6 主函數

int main() {SqQueue Q;init_queue(Q);bool ret;ret= is_empty(Q);if (ret) {printf("SqQueue is empty\n");}else{printf("SqQueue is not empty\n");}enqueue(Q, 3);enqueue(Q, 4);enqueue(Q, 5);enqueue(Q, 6);ret = enqueue(Q, 7);ret =  enqueue(Q, 8);if (ret) {printf("SqQueue success\n");}else{printf("SqQueue failed\n");}ElementType element;ret  =  dequeue(Q, element);if (ret) {printf("dequeue success\n");}else{printf("dequeue failed\n");}ret =  enqueue(Q, 8);if (ret) {printf("SqQueue success\n");}else{printf("SqQueue failed\n");}return 0;
}

?3.3循環隊列的鏈式存儲實現(單向循環鏈表)

隊頭指針為front,隊尾指針為rear;

隊空的判斷條件:front== rear

隊滿的判定條件:front ==?rear->next

3.3.1 代碼實戰

typedef int ElemType;
typedef struct LNode {ElemType data;struct LNode* next;
}LNode, *LinkList;
3.3.1.1 初始化
void CircleQueue(LinkList &front,LinkList &rear) {front=(LinkList)malloc(sizeof(LNode));rear = front;rear->next = front;EnQueue(front,rear,3);EnQueue(front,rear,3);DeQueue(front,rear);DeQueue(front,rear);DeQueue(front,rear);}
3.3.1.2 入隊
void EnQueue(LinkList &front,LinkList &rear, ElemType x) {LinkList pnew;if (rear->next == front) {pnew = (LinkList)malloc(sizeof(LNode));rear->data = x;pnew->next = rear->next;rear->next = pnew;rear = pnew;}else {rear->data =x;rear = rear->next;}
}
3.3.1.2 出隊
void DeQueue(LinkList &front,LinkList &rear) {if (front == rear) {printf("the queue is empty\n");}else {printf("the valude=%d\n",front->data);front = front->next;}}

參考地址:https://www.51cto.com/article/656335.html

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

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

相關文章

(十 四)趣學設計模式 之 策略模式!

目錄 一、 啥是策略模式?二、 為什么要用策略模式?三、 策略模式的實現方式四、 策略模式的優缺點五、 策略模式的應用場景六、 總結 🌟我的其他文章也講解的比較有趣😁,如果喜歡博主的講解方式,可以多多支…

探秘基帶算法:從原理到5G時代的通信變革【三】Turbo 編解碼

文章目錄 2.2 Turbo 編解碼2.2.1 基本概念與系統構成2.2.2 編碼過程分步解析交織器遞歸系統卷積編碼器復接器總結 2.2.3 譯碼算法分類與原理Turbo碼的強大主要來源于其解碼器理論基礎解碼過程詳解交織與解交織譯碼算法總結 2.2.4 Turbo碼的應用場景無線通信衛星通信深空通信 2.…

Yocto + 樹莓派攝像頭驅動完整指南

—— 從驅動配置、Yocto 構建,到 OpenCV 實戰 在樹莓派上運行攝像頭,在官方的 Raspberry Pi OS 可能很簡單,但在 Yocto 項目中,需要手動配置驅動、設備樹、軟件依賴 才能確保攝像頭正常工作。本篇文章從 BSP 驅動配置、Yocto 關鍵…

TCP協議(20250304)

1. TCP TCP: 傳輸控制協議(Transmission Control Protocol),傳輸層協議之一(TCP,UDP) 2. TCP與UDP UDP(用戶數據報協議) 面向數據報無連接不安全不可靠(盡最大努力交…

NModbus 連接到Modbus服務器(Modbus TCP)

1、在項目中通過NuGet添加NModbus,在界面中添加一個Button。 using NModbus.Device; using NModbus; using System.Net.Sockets; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Docu…

【零基礎到精通Java合集】第十八集:多線程與并發編程-線程池與Callable/Future應用

課程標題:線程池與Callable/Future應用(15分鐘) 目標:掌握線程池的創建與管理,理解Callable任務與Future異步結果處理機制 0-1分鐘:課程引入與線程池意義 以“銀行窗口服務”類比線程池:復用固定資源(柜員)處理多任務(客戶)。說明線程池的核心價值——避免頻繁創建…

【leetcode hot 100 238】除自身以外數組的乘積

解法一:(左右乘積列表)利用索引左側所有數字的乘積和右側所有數字的乘積(即前綴與后綴)相乘得到答案。 class Solution {public int[] productExceptSelf(int[] nums) {int len nums.length;int[] L new int[len]; …

BUU44 [BJDCTF2020]ZJCTF,不過如此1 [php://filter][正則表達式get輸入數據][捕獲組反向引用][php中單雙引號]

題目: 我仿佛見到了一位故人。。。也難怪,題目就是ZJCTF 按要求提交/?textdata://,I have a dream&filenext.php后: ......不太行,好像得用filephp://filter/convert.base64-encode/resourcenext.php 耶?那 f…

[Web 安全] PHP 反序列化漏洞 —— POP 鏈構造思路

關注這個專欄的其他相關筆記:[Web 安全] 反序列化漏洞 - 學習筆記-CSDN博客 0x01:什么是 POP 鏈? POP 鏈(Payload On Purpose Chain)是一種利用 PHP 中的魔法方法進行多次跳轉以獲取敏感數據的技術。它通常出現在 CTF…

擴散語言模型:從圖像生成到文本創造的范式躍遷

近年來,擴散模型(Diffusion Models)在人工智能領域異軍突起,尤其在圖像生成任務中取得了令人矚目的成就,如 Stable Diffusion 等模型已成為生成高質量圖像的標桿。這種成功激發了研究者們的好奇心:擴散模型的魔力能否從視覺領域延伸至自然語言處理(NLP),為文本生成帶來…

大模型工程師學習日記(十):基于 LangChain 構建向量存儲和查詢 Qdrant

Qdrant介紹 Qdrant(讀作:quadrant /kwɑdr?nt/ n. 象限;象限儀;四分之一圓)是一個向量相似度搜索引擎。它提供了一個生產就緒的服務,具有方便的 API 來存儲、搜索和管理點 - 帶有附加載荷的向量。Qdrant專…

DeepSeek 助力 Vue3 開發:打造絲滑的網格布局(Grid Layout)

前言:哈嘍,大家好,今天給大家分享一篇文章!并提供具體代碼幫助大家深入理解,徹底掌握!創作不易,如果能幫助到大家或者給大家一些靈感和啟發,歡迎收藏關注哦 💕 目錄 Deep…

deepseek、騰訊元寶deepseek R1、百度deepseekR1關系

分析與結論 區別與聯系 技術基礎與定制方向: DeepSeek官網R1版本:作為基礎版本,通常保留通用性設計,適用于廣泛的AI應用場景(如自然語言處理、數據分析等)。其優勢在于技術原生性和官方直接支持。騰訊元寶…

外貿獨立站使用wordpress模板與定制哪個SEO效果好

使用WordPress模板搭建的外貿獨立站與定制站的SEO效果,可以從以下幾個方面進行分析: 1. 內容質量是SEO的核心 內容質量確實是SEO的關鍵,無論使用模板還是定制開發,優質、相關、原創的內容都是提升排名的基礎。內容能夠解決用戶問…

Golang語法特性總結

1.認識Golang代碼特性 package main //1.包含main函數的文件就是一個main包--當前程序的包名// import "fmt" // import "time" import("fmt""time" )//3.同時包含多個包 4.強制代碼風格:函數的 { 一定和函數名在同一行,否…

AI賦能校園安全:科技助力預防與應對校園霸凌

校園本應是學生快樂學習、健康成長的地方,然而,校園霸凌卻成為威脅學生身心健康的隱形“毒瘤”。近年來,隨著人工智能(AI)技術的快速發展,AI在校園安全領域的應用逐漸成為解決校園霸凌問題的新突破口。通過…

易語言模擬真人鼠標軌跡算法 - 防止游戲檢測

一.簡介 鼠標軌跡算法是一種模擬人類鼠標操作的程序,它能夠模擬出自然而真實的鼠標移動路徑。 鼠標軌跡算法的底層實現采用C/C語言,原因在于C/C提供了高性能的執行能力和直接訪問操作系統底層資源的能力。 鼠標軌跡算法具有以下優勢: 模擬…

運營商三要素API:構建安全信任的橋梁

引言 在數字經濟時代,身份驗證已成為各類業務場景的基礎需求。運營商三要素API作為一種高效的身份核驗工具,通過對接運營商數據,實現對用戶姓名、身份證號碼、手機號碼三項關鍵信息的實時校驗,為各行業提供可靠的身份認證解決方案…

Spring Boot 與 MyBatis 版本兼容性

初接觸Spring Boot,本次使用Spring Boot版本為3.4.3,mybatis的起步依賴版本為3.0.0,在啟動時報錯,報錯代碼如下 org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name userMapper…

GCN從理論到實踐——基于PyTorch的圖卷積網絡層實現

Hi,大家好,我是半畝花海。圖卷積網絡(Graph Convolutional Network, GCN)是一種處理圖結構數據的深度學習模型。它通過聚合鄰居節點的信息來更新每個節點的特征表示,廣泛應用于社交網絡分析、推薦系統和生物信息學等領…