數據結構_隊列Queue(C語言實現)

一、隊列的基本概念

1.隊列定義

隊列是一種先進先出的線性表數據結構(First in First out),現實中的例子就是,排隊購票,先排隊的先購票,購完票之后直接從這個隊中離開,后來的在這個隊后面排隊,這就是隊列。

如圖;
在這里插入圖片描述
這就是一個空的隊列,從隊尾入隊,從隊頭出隊

2.常見的基本操作

  • initQueue:初始化隊列
  • empty: 判斷隊列是否為空
  • push:入隊操作
  • pop:出隊操作
  • Front:獲取隊頭元素

3.數據結構定義

為了鍛煉高度模塊化(分層設計),這里我們直接嵌套,不在Queue中直接定義數組,而是重新抽象出一個獨立的vector數據結構作為底層容器,讓Queue通過組合的方式使用vector來實現其功能。這種設計強調關注點分離,將內存管理的職責交給vector模塊,而Queue模塊只需專注于隊列特有的邏輯操作。

typedef struct Queue {vector* data;int size,head,tail;//size記錄當前隊列有多少元素
}Queue;

二、代碼實現

首先引用頭文件,宏定義隊列的開始元素為多少,定義vector及Queue

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <stdbool.h>
#define BEGIN_SIZE 6
typedef struct vector {int* val;int size;//記錄當前容量
}vector;
typedef struct Queue {vector* data;int size,head,tail;//size記錄當前隊列有多少元素
}Queue;

初始化Queue

Queue *initQueue() {Queue* q = (Queue*)malloc(sizeof(Queue));q->data = initVector();q->head = q->tail = q->size = 0;return q;
}

要想初始化Queue,那么也就要初始化vector

vector* initVector()
{vector * v=(vector*)malloc(sizeof(vector));v->size = BEGIN_SIZE;v->val = (int*)malloc(sizeof(int) * BEGIN_SIZE);return v;
}

這樣隊列的初始化就實現了,下來我們依次實現隊列的基本功能:

  • empty: 判斷隊列是否為空
  • push:入隊操作
  • pop:出隊操作
  • Front:獲取隊頭元素

empty():

bool empty(Queue* q) {return q->size == 0;//如果當前元素的個數等于 0 ,那么則證明隊列為空
}

push():

int push(Queue* q, int val) {checkFull(q); /*如果隊列已經滿了,擴容隊列*/q->data->val[q->tail++] = val;q->size++;return 1;
}

pop():

int pop(Queue* q) {if (empty(q))/*如果隊列為空的話,則返回-1代表彈出失敗*/ {printf("pop: 隊列為空\n");return -1;}int count = 0;while (count < q->tail - 1) {q->data->val[count] = q->data->val[count + 1];count++;}q->tail--;q->size--;return 1;
}

解釋下,這里為什么count<q->tail-1 為什么不是 count<q->tail
例如,隊列中有三個元素,那么tail的值就是3,count從0開始,一共要循環到3次,最后一次的count等于 2 ,這個時候 q->data->val[count] = q->data->val[count + 1];這一句就會變為q->data->val[2] = q->data->val[3];,此時 3 這個位置是tail的位置,在內存中并沒有賦值,內存中的值是未定義的(可能是垃圾值)

Front():

int Front(Queue* q) {if (empty(q)) {printf("Front 隊列為空\n");return -1;}return q->data->val[q->head];
}

反過頭處理checkFull(),檢查隊列是否為滿,滿的話則需要擴容

checkFull():

void checkFull(Queue *q) {if (q->size == q->data->size) {int newSize = q->data->size * 2;int * newVal=(int *)realloc(q->data->val, sizeof(int) * newSize);if (newVal == NULL) {printf("error checkFull\n");exit(-1);}q->data->val = newVal;q->data->size = newSize;}return;
}

查看隊列所有元素

outAll():

void outAll(Queue* q) {printf("Queue: ");for (int i = q->head; i < q->tail; i++) {printf("%3d ", q->data->val[i]);}printf("\n");return;
}

最后釋放內存

freeQueue():

void freeQueue(Queue* q) {freeVector(q->data);free(q);return;
}

freeVector():

void freeVector(vector* v) {free(v->val);free(v);return;
}

main函數(測試函數)

int main() {Queue* q = initQueue();//初始化一個隊列pop(q);//在空隊列時彈出,應該輸出 pop: 隊列為空Front(q);//在空隊列時獲取隊頭元素,應該輸出 Front: 隊列為空srand(time(NULL));
#define MAX_OP 10for (int i = 0; i < MAX_OP; i++) {int op = rand() % 5, val = rand() % 100;switch (op) {case 0://pop操作printf("front of queue %d 彈出此元素\n", Front(q));pop(q);break;case 1:case 2:case 3:case 4://push操作printf("將 %d push進隊列\n", val);push(q, val);break;}outAll(q);}printf("隊頭元素為: %3d\n",Front(q));return 0;
}

完整代碼

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define BEGIN_SIZE 6
typedef struct vector {int* val;int size;//記錄當前容量
}vector;
typedef struct Queue {vector* data;int size, head, tail;//size記錄當前隊列有多少元素
}Queue;
vector* initVector()
{vector * v=(vector*)malloc(sizeof(vector));if (v == NULL) {printf("error initVector\n");exit(-1);}v->size = BEGIN_SIZE;v->val = (int*)malloc(sizeof(int) * BEGIN_SIZE);return v;
}
Queue *initQueue() {Queue *q = (Queue*)malloc(sizeof(Queue));if (q == NULL) {printf("error initQueue\n");exit(-1);}q->data = initVector();q->head = q->tail = q->size = 0;return q;
}
bool empty(Queue* q) {return q->size == 0;
}
void checkFull(Queue *q) {if (q->size == q->data->size) {int newSize = q->data->size * 2;int * newVal=(int *)realloc(q->data->val, sizeof(int) * newSize);if (newVal == NULL) {printf("error checkFull\n");exit(-1);}q->data->val = newVal;q->data->size = newSize;}return;
}
int push(Queue* q, int val) {checkFull(q); /*如果隊列已經滿了,擴容隊列*/q->data->val[q->tail++] = val;q->size++;return 1;
}int pop(Queue* q) {if (empty(q))/*如果隊列為空的話,則返回-1代表彈出失敗*/ {printf("pop: 隊列為空\n");return -1;}int count = 0;while (count < q->tail - 1) {q->data->val[count] = q->data->val[count + 1];count++;}q->tail--;q->size--;return 1;
}int Front(Queue* q) {if (empty(q)) {printf("Front: 隊列為空\n");return -1;}return q->data->val[q->head];
}void outAll(Queue* q) {printf("Queue: ");if (empty(q)) {printf("NULL\n");return;}for (int i = q->head; i < q->tail; i++) {printf("%3d ", q->data->val[i]);}printf("\n");return;
}void freeVector(vector* v) {free(v->val);free(v);return;
}void freeQueue(Queue* q) {freeVector(q->data);free(q);return;
}int main() {Queue* q = initQueue();//初始化一個隊列pop(q);//在空隊列時彈出,應該輸出 pop: 隊列為空Front(q);//在空隊列時獲取隊頭元素,應該輸出 Front: 隊列為空srand(time(NULL));
#define MAX_OP 10for (int i = 0; i < MAX_OP; i++) {int op = rand() % 5, val = rand() % 100;switch (op) {case 0://pop操作printf("front of queue %d 彈出此元素\n", Front(q));pop(q);break;case 1:case 2:case 3:case 4://push操作printf("將 %d push進隊列\n", val);push(q, val);break;}outAll(q);}printf("隊頭元素為: %3d\n",Front(q));return 0;
}

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

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

相關文章

C++對CPU緩存的合理利用

緩存體系 在計算機的體系結構中,存儲速度是分了好幾層: CPU緩存,又分成了L1/L2/L3等多層緩存,我們暫時看成同一層。訪問速度最快 內存,訪問速度次之,大概是CPU緩存的幾十分之一 硬盤,訪問速度最慢,是內存訪問速度的幾十分之一 所以,在計算機體系結構中,把下一層的數…

貝葉斯定理:理解概率更新與實際場景應用

貝葉斯定理及其應用&#xff1a;從基礎到實戰 貝葉斯定理&#xff08;Bayes’ Theorem&#xff09;是概率論中最基礎也是最強大的工具之一。它通過將先驗知識與新證據結合&#xff0c;能夠幫助我們在不確定的情況下做出更加精準的判斷。本文將從貝葉斯定理的核心概念、公式開始…

組件之間的傳遞參數傳遞(常用父向子傳遞)

現在&#xff0c;有子組件<MdsWxSourceDetailref"mdsWx":rank-obj"activeRankObj":media-name"activeObj.mediaName" :error-info"activeErrorInfo" ></MdsWxSourceDetail>以上代碼在MdsIndexRankDetail&#xff0…

java畢業設計-基于springboot區塊鏈的電子病歷數據共享平臺設計與實現(附源碼數據庫文檔資料)

博主介紹&#xff1a;??碼農一枚 &#xff0c;專注于大學生項目實戰開發、講解和畢業&#x1f6a2;文撰寫修改等。全棧領域優質創作者&#xff0c;博客之星、掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java、小程序技術領域和畢業項目實戰 ??技術范圍&#xff1a;&am…

【新啟航】3D 逆向抄數的三維能力架構:數據采集工具操作 × 幾何處理算法應用 × 行業場景適配技能

摘要3D 逆向抄數的落地效果依賴多維度能力協同&#xff0c;本文提出 “數據采集工具操作 - 幾何處理算法應用 - 行業場景適配技能” 的三維能力架構。通過拆解各維度核心要素&#xff0c;分析數據采集工具&#xff08;激光、結構光等&#xff09;的操作要點&#xff0c;解析幾何…

RocksDB 在 macOS M 系列 上運行時報錯的解決方案

問題現象 項目中引入可Kafka Stream &#xff0c;Windows下啟動不報錯 &#xff0c;但是在 macOS M系列 環境下就會報錯&#xff0c;初步定位是使用 Java 項目調用 RocksDB 時&#xff0c;運行過程中出現以下報錯&#xff1a; UnsatisfiedLinkError: no rocksdbjni in java.lib…

深度學習之第五課卷積神經網絡 (CNN)如何訓練自己的數據集(食物分類)

簡介 之前一直使用的是現有人家的數據集&#xff0c;現在我們將使用自己的數據集進行訓練。 基于卷積神經網絡 (CNN) 的 MNIST 手寫數字識別模型 一、訓練自己數據集 1.數據預處理 我們現在有這樣的數據集如下圖&#xff1a; 每一個文件夾里面有著對應的圖片。我們要將這些…

【Big Data】AI賦能的ClickHouse 2.0:從JIT編譯到LLM查詢優化,下一代OLAP引擎進化路徑

目錄 1. 什么是ClickHouse&#xff1f; 2. 誕生背景與發展歷程 3. 架構設計解析 3.1 存儲引擎&#xff1a;MergeTree家族 3.2 分布式模型&#xff1a;分片與副本 3.3 執行流程&#xff1a;向量化與并行計算 4. 解決的問題與適用場景 4.1 典型問題 4.2 適用場景 5. 關…

Vue實踐篇-02,AI生成代碼

問題描述這個是需求&#xff1a;動態表格、表格里邊下拉框&#xff0c;彈框選擇基礎的列表&#xff0c;還行&#xff0c;這種真的是一時不知如何是好。打算晚上吃了飯找前端同事&#xff0c;幫忙看看。晚飯前&#xff0c;AI一下看看。結果&#xff0c;驚為天人&#xff01;&…

2025-08-28-zabbix5.0創建監控項通過腳本簡單實現監控oracle11g的磁盤組和表空間的使用量

title: zabbix5.0創建監控項通過腳本簡單實現監控oracle11g的磁盤組和表空間的使用量 authors: Loong date: 2025-08-28使用SQLPLUS配合crontab任務 用來執行sql獲取信息的腳本 /home/oracle/zabbix_oracle_check.sh #!/bin/bash #用于zabbix agent被動模式的 非入侵性的檢測 #…

MySQL-Redo Log(重做日志)

MySQL 的 Redo Log&#xff08;重做日志&#xff09;是 InnoDB 存儲引擎的核心組件之一&#xff0c;是保證數據庫持久性&#xff08;Durability&#xff09; 和崩潰恢復&#xff08;Crash Recovery&#xff09; 的關鍵機制。1. 什么是 Redo Log&#xff1f;它的核心作用是什么&…

嵌入式linux相機(2)

本人從0開始學習linux&#xff0c;使用的是韋東山的教程&#xff0c;在跟著課程學習的情況下的所遇到的問題的總結,理論雖枯燥但是是基礎。本人將前幾章的內容大致學完之后&#xff0c;考慮到后續驅動方面得更多的開始實操&#xff0c;后續的內容將以韋東山教程Linux項目的內容…

云計算學習100天-第34天 -zabbix監控2

SourceURL:file:///home/student/Documents/zabbix.doczabbix服務器配置1. 拷貝zabbix軟件包到pubserver#在此之前先從真機拷貝安裝包[rootserver1 ~]# scp /linux-soft/s2/zzg/zabbix_soft/*.rpm 192.168.88.5:/root/#然后拷貝到pubserver[rootzabbixserver ~]# scp /linux-so…

貓頭虎AI分享:無需OCR,基于ColQwen2、Qwen2.5和Weaviate對PDF進行多模態RAG的解決方案

無需OCR&#xff0c;基于ColQwen2、Qwen2.5和Weaviate對PDF進行多模態RAG的解決方案 關鍵詞&#xff1a;多模態RAG、ColQwen2、Qwen2.5-VL、Weaviate 向量數據庫、PDF 檢索問答、無需 OCR、ColBERT 多向量、跨模態檢索、MaxSim 相似度、知識庫構建、AI 文檔處理、視覺語言模型、…

HTML第三課:特殊元素

HTML第三課&#xff1a;特殊元素特殊元素代碼展示特殊元素 不在行級元素和塊級元素概念里面的元素無法控制沒有寬高的元素 代碼展示 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewpo…

藍橋杯算法之基礎知識(5)

目錄 Ⅰ.in方法的使用 Ⅱ.字典的使用 Ⅲ.1MB 、KB、 B、 b(即bit)的轉換&#xff08;必學&#xff09; Ⅳ.閏年or平年 Ⅴ.count和counter方法 1. count() 方法的使用場景 2. Counter 類的介紹 3. count() 與 Counter 的區別 4. Counter 的高級應用 5.Counter的另一種使用 Ⅵ.ma…

lesson52:CSS進階指南:雪碧圖與邊框技術的創新應用

目錄 一、CSS雪碧圖&#xff1a;從性能優化到交互革命 1.1 技術原理與現代價值 1.2 2025年實現工具與自動化流程 1.2.1 構建工具集成方案 1.2.2 在線生成工具推薦 1.3 高級應用案例與代碼實現 1.3.1 多狀態按鈕系統 1.3.2 響應式雪碧圖實現 1.4 最佳實踐與性能優化 二…

案例——從零開始搭建 ASP.NET Core 健康檢查實例

1. 項目創建與基礎設置 創建新項目 首先&#xff0c;創建一個新的 ASP.NET Core Web API 項目&#xff1a; dotnet new webapi -n HealthCheckDemo cd HealthCheckDemo添加必要的 NuGet 包 添加健康檢查相關的 NuGet 包&#xff1a; dotnet add package Microsoft.AspNetCore.D…

【Java生產級避坑指南】8. Tomcat線程池下的內存地雷:ThreadLocal泄漏檢測與實戰解決

摘要:某金融交易系統(Spring Boot 2.7 + Tomcat 9)在線上運行時出現嚴重內存泄漏:堆內存(4GB)72小時內耗盡并觸發OOM,日均200萬請求場景下,Full GC頻率從正常1次/天飆升至6次/小時。排查發現,根源是ThreadLocal未清理——Tomcat線程池復用線程時,UserInfo等大對象被T…

云端職達:你的AI求職專屬獵頭,顛覆傳統招聘模式

在求職的“金三銀四”或“金九銀十”&#xff0c;每一分每一秒都彌足珍貴。面對浩如煙海的招聘信息&#xff0c;你是否還在花費大量時間一條條篩選、重復投遞簡歷&#xff0c;最終卻常常石沉大海&#xff1f;傳統求職方式的低效和“已讀不回”的窘境&#xff0c;讓許多求職者感…