數據結構:用數組實現隊列(Implementing Queue Using Array)

目錄

第1步:設計藍圖 (The Struct)

第2步:隊列的誕生 (創建與初始化)

第3步:狀態檢查 (判滿與判空)

第4步:核心操作 (入隊與出隊)

入隊 (Enqueue)

出隊 (Dequeue)

第5步:善后工作 (銷毀隊列)


現在,我們聚焦于如何用代碼一步步地實現這個最終方案。我們從零開始,只寫必要的代碼,并在每一步都解釋為什么這么寫。

數據結構:隊列(Queue)與循環隊列(Circular Queue)-CSDN博客


第1步:設計藍圖 (The Struct)

從第一性原理出發,要描述一個隊列,我們需要知道哪些信息?

  1. 數據存放在哪里? -> 需要一個指針指向我們的數據區。 (int* data)

  2. 隊列的總容量是多少? -> 需要一個變量記錄容量,這樣我們的取模運算才有依據。 (int capacity)

  3. 隊頭在哪里? -> 需要一個下標作為隊頭指針。 (int front)

  4. 隊尾在哪里? -> 需要一個下標作為隊尾指針。 (int rear)

把這些信息組合起來,就形成了我們的“藍圖”——結構體定義。

【代碼實現 1:結構體定義】

#include <stdio.h>
#include <stdlib.h> // 我們需要用 malloc 和 free 來動態管理內存// 循環隊列的藍圖
typedef struct {int* data;      // 指向一塊用于存儲數據的內存int capacity;   // 這塊內存的總容量 (實際能存的元素數是 capacity-1)int front;      // 隊頭元素的下標int rear;       // 隊尾元素的下一個位置的下標
} CircularQueue;

這就像建房子前畫的設計圖,它定義了我們的隊列由哪幾部分構成。


第2步:隊列的誕生 (創建與初始化)

有了藍圖,我們就可以“施工”了,即創建一個具體的隊列實例。創建一個容量為 k 的隊列,需要做什么?

  1. CircularQueue 這個結構體本身分配一塊內存。

  2. data 指針指向的數組分配一塊內存。根據我們的最終方案,要存儲 k 個元素,需要 k+1 的數組空間。

  3. 設置初始狀態。一個空隊列的初始狀態是什么?根據我們的約定,是 frontrear 相等。最簡單的就是都設為 0。

【代碼實現 2:創建隊列函數】

// 功能:創建一個能容納 k 個元素的空隊列
CircularQueue* createQueue(int k) {// 1. 為隊列的整體結構分配內存CircularQueue* q = (CircularQueue*)malloc(sizeof(CircularQueue));// 防御性編程:檢查內存是否分配成功if (!q) {perror("Failed to allocate memory for queue structure");return NULL;}// 2. 設置容量。注意,我們需要 k+1 個空間q->capacity = k + 1;// 3. 為實際存儲數據的數組分配內存q->data = (int*)malloc(q->capacity * sizeof(int));// 再次進行防御性編程if (!q->data) {perror("Failed to allocate memory for queue data");free(q); // 如果數據區分配失敗,必須釋放之前為結構體分配的內存,防止內存泄漏return NULL;}// 4. 初始化頭尾指針,表示隊列為空q->front = 0;q->rear = 0;// 5. 返回創建好的隊列實例return q;
}

第3步:狀態檢查 (判滿與判空)

在進行核心操作(入隊/出隊)之前,必須先能準確判斷隊列的狀態。這就像開車前要先看油表和儀表盤。

  • 判空 (isEmpty): 我們的約定是 front == rear

  • 判滿 (isFull): 我們的約定是隊尾的下一個位置是隊頭,即 (rear + 1) % capacity == front

這些是實現后續功能的基石。

【代碼實現 3:狀態判斷函數】

// 功能:判斷隊列是否為空
int isEmpty(CircularQueue* q) {// 直接翻譯我們的約定: front 等于 rearreturn q->front == q->rear;
}// 功能:判斷隊列是否為滿
int isFull(CircularQueue* q) {// 直接翻譯我們的約定: (rear + 1) 對 capacity 取模后等于 frontreturn (q->rear + 1) % q->capacity == q->front;
}

這兩個函數非常簡潔,但它們是整個循環隊列邏輯的核心。


第4步:核心操作 (入隊與出隊)

現在,萬事俱備,我們可以實現隊列的兩個核心靈魂操作了。

入隊 (Enqueue)

要將一個值 value 加入隊尾,需要三步:

  1. 檢查:隊列是不是已經滿了?如果滿了,就不能再入了。這是操作的“前置條件”。

  2. 放置:如果沒滿,就把 value 放到 rear 指向的位置。

  3. 更新rear 指針需要向前移動一位,為下一次入隊做準備。別忘了,要用取模運算來實現循環。

【代碼實現 4:入隊函數】

// 功能:將一個元素 value 加入隊尾
int enqueue(CircularQueue* q, int value) {// 1. 前置條件檢查if (isFull(q)) {printf("入隊失敗:隊列已滿。\n");return 0; // 返回 0 表示失敗}// 2. 放置數據q->data[q->rear] = value;// 3. 更新隊尾指針,使用取模運算實現循環q->rear = (q->rear + 1) % q->capacity;return 1; // 返回 1 表示成功
}

出隊 (Dequeue)

要從隊頭取出一個元素,邏輯類似:

  1. 檢查:隊列是不是空的?如果是空的,就無元素可取。這是操作的“前置條件”。

  2. 取出:如果沒空,就從 front 指向的位置獲取元素值。

  3. 更新front 指針需要向前移動一位,指向新的隊頭。同樣,要用取模運算。

【代碼實現 5:出隊函數】

// 功能:從隊頭取出一個元素,并通過指針 pValue 返回該元素的值
int dequeue(CircularQueue* q, int* pValue) {// 1. 前置條件檢查if (isEmpty(q)) {printf("出隊失敗:隊列為空。\n");return 0; // 失敗}// 2. 取出數據*pValue = q->data[q->front];// 3. 更新隊頭指針,使用取模運算實現循環q->front = (q->front + 1) % q->capacity;return 1; // 成功
}

第5步:善后工作 (銷毀隊列)

我們用 malloc 申請了內存,在程序結束前,作為一個負責任的程序員,必須將這些內存歸還給操作系統,否則會造成內存泄漏。

銷毀的順序應該是:先釋放內部的 data 數組,再釋放隊列結構體本身。

【代碼實現 6:銷毀函數】

// 功能:釋放隊列占用的所有內存
void destroyQueue(CircularQueue* q) {if (q != NULL) {// 1. 如果 data 指針有效,則先釋放它指向的數組內存if (q->data != NULL) {free(q->data);}// 2. 再釋放隊列結構體本身的內存free(q);}
}

至此,我們已經從一張“藍圖”開始,一步步地構建了創建、檢查、操作、銷毀一個完整循環隊列所需的所有代碼。每一步的實現都緊密圍繞著我們最初通過第一性原理推導出的核心約定。

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

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

相關文章

Boost庫核心組件與應用

一、BOOST 庫簡介&#xff1a;C 開發者的 “擴展工具集” 在 C 編程領域&#xff0c;除了標準庫&#xff08;STL&#xff09;外&#xff0c;BOOST 庫是最具影響力的第三方庫之一。它由全球數百位開發者共同維護&#xff0c;包含超過 160 個高質量的組件&#xff0c;覆蓋從基礎…

機器學習 [白板推導](十二)[卡曼濾波、粒子濾波]

15. 線性動態系統&#xff08;卡曼濾波&#xff0c;Kalman Filter&#xff09; 15.1. 概述 15.1.1. 背景介紹 變量隨時間變化的系統叫做動態系統&#xff0c;其中隱變量取值離散的是隱馬爾可夫模型&#xff08;HMM&#xff09;&#xff0c;而隱變量取值連續的分為線性動態系統…

RH134 訪問網絡附加存儲知識點

1. NFS 的主要功能是什么&#xff1f;答&#xff1a;NFS是一種分布式文件系統協議&#xff0c;主要功能包括&#xff1a;允許遠程計算機通過網絡訪問共享文件。 實現文件系統在客戶端和服務器之間的透明訪問。支持文件的共享、讀取和寫入&#xff0c;使得多個 …

組合模式及優化

組合模式是一種結構型設計模式&#xff0c;其核心思想是將對象組合成樹形結構&#xff0c;以表示“部分-整體”的層次關系&#xff0c;使得用戶對單個對象和組合對象的使用具有一致性。 一、介紹 核心角色 組合模式包含以下3個關鍵角色&#xff1a; 抽象組件&#xff08;Compon…

【wmi異常】關于taskkill命令提示“錯誤:找不到” 以及無法正常獲取設備機器碼的處理辦法

記錄一下我的解決方案。 我先查閱了這篇博客&#xff1a;https://blog.csdn.net/qq_45698181/article/details/138957277 發現他寫的批處理不知怎么執行不了&#xff0c;后來問了ai又可以執行了&#xff0c;估計是csdn防盜版格式問題 這里寫一下我跟ai的對話&#xff0c;大家可…

制造裝配、倉儲搬運、快遞裝卸皆適配!MinkTec 彎曲形變傳感器助力,讓人體工學改變勞動生活

【導語】Minktec 最新實驗顯示&#xff1a;將Minktec 柔性彎曲形變傳感器FlexTail 貼于受試者背部&#xff0c;記錄 1 分鐘內從洗碗機取餐具的動作&#xff0c;結合配套的flexlib -專用Python庫分析&#xff0c;不僅量化出 “越低越傷腰” 的結論&#xff0c;更為制造裝配、物流…

Nginx蜘蛛請求智能分流:精準識別爬蟲并轉發SEO渲染服務

> 一招解決搜索引擎爬蟲無法解析現代前端框架的痛點,提升網站收錄率與SEO排名! **痛點場景**:你的網站采用Vue/React等前端框架構建,頁面內容依賴JavaScript動態渲染。搜索引擎爬蟲訪問時,只能抓取到空HTML骨架,無法獲取真實內容,導致網站收錄率低、SEO效果差。 --…

鏈表。。。

目錄 5.1 鏈表的結點 5.2 插入 5.3 鏈表長度 5.4 查找 5.5 指定位置刪除 5.6 代碼 5.1 鏈表的結點 一個結點包括&#xff1a;值和指向下一個結點的指針。 package com.qcby.鏈表;public class Node {int value;Node next;public Node(int val){valueval;}Overridepublic…

私人AI搜索新突破:3步本地部署Dify+Ollama+QwQ,搜索能力MAX

1.安裝Docker容器 本地部署Dify要先安裝Docker桌面版&#xff0c;跟Ollama一樣簡單&#xff0c;也是去官網下載對應版本文件&#xff0c;直接安裝就OK。 2&#xff1a;安裝Dify 安裝 Dify 簡單的方式就是git clone&#xff0c;復制其github地址github.com/langgenius/dify&am…

(2-10-1)MyBatis的基礎與基本使用

目錄 0.前置小節 1. MyBatis 框架介紹 1.1 軟件開發中的框架 1.2 使用框架的好處 1.3 SSM 開發框架 1.4 什么是 MyBatis 1.5 MyBatis 的開發流程 2. MyBatis 的開發流程 2.0 MyBatis的工作流程 2.1 引入 MyBatis 依賴 00.base(目錄、pom、單元測試、Junit4) 01.Cal…

StarRocks集群部署

Starrocks 是一款基于 MPP 架構的高性能實時分析型數據庫&#xff0c;專為 OLAP&#xff08;聯機分析處理&#xff09;場景 設計&#xff0c;尤其擅長處理海量數據的實時分析、復雜查詢和多維統計。 硬件 CPU&#xff1a;StarRocks依靠AVX2指令集充分發揮其矢量化能力。因此&am…

【CPP】自己實現一個CPP小工具demo,可以擴展其他選項

自己寫CPP腳本小工具1. 思路描述2. 代碼實現2.1 代碼文件CppTool.cpp2.2 CMakeLists.txt3. 工具示例3.1 幫助信息3.2 工具用法3.3 實際使用1. 思路描述 實現一個簡單的命令行工具。內容包括&#xff1a; 命令幫助信息參數檢查&#xff0c;參數解析等功能。執行其他命令。將指…

如何使用嵌入模型創建本地知識庫Demo

為data目錄下的txt文檔用阿里百煉的文本嵌入模型創建一個本地知識庫import os from llama_index.core import ,Settings, SimpleDirectoryReader, VectorStoreIndex from llama_index.core.node_parser import SentenceSplitter from llama_index.llms.dashscope import DashSc…

SpringBoot 整合 Langchain4j:系統提示詞與用戶提示詞實戰詳解

> 掌握提示詞工程的核心技巧,讓你的AI應用效果提升300%! **真實痛點**:為什么同樣的模型,別人的應用精準專業,而你的卻答非所問?關鍵在于提示詞工程!本文將揭秘如何通過系統提示詞與用戶提示詞的巧妙配合,打造專業級AI應用。 --- ### 一、Langchain4j 核心概念…

Sklearn 機器學習 郵件文本分類 加載郵件數據

??親愛的技術愛好者們,熱烈歡迎來到 Kant2048 的博客!我是 Thomas Kant,很開心能在CSDN上與你們相遇~?? 本博客的精華專欄: 【自動化測試】 【測試經驗】 【人工智能】 【Python】 Sklearn 機器學習 郵件文本分類 - 加載郵件數據 在自然語言處理(NLP)中,郵件文本分…

騰訊云開發小程序工具箱使用心得

一、核心優勢與使用體驗 作為首批使用騰訊云開發&#xff08;CloudBase&#xff09;工具箱的開發者&#xff0c;我深刻感受到其通過CloudBase AI與MCP服務重構開發范式的創新價值。結合微信小程序開發場景&#xff0c;該平臺在以下維度表現突出&#xff1a; 1. AI驅動的全棧開發…

機械加工元件——工業精密制造的璀璨明珠

在工業制造的宏大畫卷中&#xff0c;機械加工元件猶如璀璨的明珠&#xff0c;以其卓越的性能和精湛的工藝&#xff0c;為各行各業的發展注入了源源不斷的動力。它們雖形態各異&#xff0c;功能不同&#xff0c;卻在無數產品中攜手合作&#xff0c;展現出科技與柔性的完美融合。…

【八股】Redis-中小廠精要八股

Redis 基礎 redis為什么這么快 (高) [!NOTE] 最首要的是Redis是純內存操作, 比磁盤要快3個數量級同時在與內存操作中采用了非阻塞I/O多路復用機制來提高并發量并且基于Redis的IO密集型&#xff0c;采用單線程操作, 免去了線程切換開銷Redis 內置了多種優化過后的數據結構實現…

C++字符串(string)操作解析:從基礎到進階

1. 字符串基礎&#xff1a;大小與容量cppvoid test1() {string s1("Hello World");cout << "size : " << s1.size() << endl; // 輸出字符串長度cout << "capacity " << s1.capacity() << endl; // 輸出字…

蘑兔音樂:音樂創作的魔法棒

在這個充滿創意與可能的時代&#xff0c;人人都有一顆渴望表達音樂之心。但傳統音樂創作&#xff0c;復雜的樂理、昂貴的設備&#xff0c;總讓人望而卻步。別擔心&#xff01;蘑兔 AI 音樂強勢來襲&#xff0c;它就是那個能讓音樂小白也能搞創作的神奇工具&#xff01;?靈感模…