數據結構C語言練習(兩個棧實現隊列)

一、引言

在數據結構的學習中,我們經常會遇到一些有趣的問題,比如如何用一種數據結構去實現另一種數據結構的功能。本文將深入探討 “用棧實現隊列” 這一經典問題,詳細解析解題思路、代碼實現以及每個函數的作用,幫助讀者更好地理解數據結構之間的轉換與應用。

練習題:

1.力扣 232. 用棧實現隊列

二、解題思路

隊列的特點是先進先出(FIFO),而棧的特點是后進先出(LIFO)。為了用棧實現隊列,我們使用兩個棧:pushST?和?popST

  • 入隊操作(push:直接將元素壓入?pushST?棧。
  • 出隊操作(pop)和獲取隊頭元素(peek:若?popST?棧為空,將?pushST?棧中的所有元素依次彈出并壓入?popST?棧,此時?popST?棧的棧頂元素就是隊列的隊頭元素,然后進行相應的彈出(pop)或返回(peek)操作。
  • 判空操作(empty:只有當?pushST?和?popST?兩個棧都為空時,隊列才為空。

三、數據結構定義

typedef int STDataType;
typedef struct Stack {STDataType* _a;int _top;int _capacity;
} Stack;typedef struct {Stack pushST;Stack popST;
} MyQueue;
  • Stack?結構體表示棧,包含存儲數據的數組?_a、棧頂指針?_top?和容量?_capacity
  • MyQueue?結構體包含兩個棧?pushST?和?popST,用于實現隊列功能。

四、棧的基礎操作函數詳解

1. 棧初始化(StackInit

void StackInit(Stack* ps) {ps->_a = NULL;ps->_capacity = ps->_top = 0;
}
  • 功能:初始化棧,將棧的存儲數組、容量和棧頂指針都置為初始狀態。
  • 步驟:將?_a?置為?NULL_capacity?和?_top?置為?0,表示空棧。

2. 入棧操作(StackPush

void StackPush(Stack* ps, STDataType data) {assert(ps);if (ps->_capacity == ps->_top) {int newCapacity = ps->_capacity == 0 ? 4 : 2 * ps->_capacity;STDataType* tmp = (STDataType*)realloc(ps->_a, newCapacity * sizeof(STDataType));if (tmp == NULL) {perror("Fail realloc");exit(1);}ps->_a = tmp;ps->_capacity = newCapacity;}ps->_a[ps->_top++] = data;
}
  • 功能:將元素壓入棧頂。
  • 步驟
    1. 檢查棧是否已滿,若滿則擴容(初始容量為 4,每次擴容為原來的 2 倍)。
    2. 擴容后將新元素插入到棧頂位置,更新?_top?指針。

三、隊列操作函數詳解

1.?myQueueCreate:創建隊列

MyQueue* myQueueCreate() {MyQueue* pq = (MyQueue*)malloc(sizeof(MyQueue));StackInit(&pq->pushST);StackInit(&pq->popST);return pq;
}

?

  • 功能:創建隊列實例。
  • 步驟
    • 為?MyQueue?分配內存,確保存儲隊列相關數據的空間。
    • 初始化內部的?pushST(入) 和?popST(出) 棧,通過?StackInit?清空棧狀態,為后續操作做準備。

2.?myQueuePush:入隊操作

void myQueuePush(MyQueue* obj, int x) {StackPush(&obj->pushST, x);
}

?

  • 功能:將元素加入隊列尾部。
  • 原理:直接利用?pushST?棧的入棧操作。入隊操作只需關注元素添加,無需處理順序,因此直接將元素壓入?pushST,后續出隊時再通過?popST?調整順序。

3.?myQueuePop:出隊操作(取后刪)

int myQueuePop(MyQueue* obj) {if (StackEmpty(&obj->popST)) {while (!StackEmpty(&obj->pushST)) {StackPush(&obj->popST, StackTop(&obj->pushST));StackPop(&obj->pushST);}}int top = StackTop(&obj->popST);StackPop(&obj->popST);return top;
}

?

  • 功能:移除并返回隊列頭部元素。
  • 步驟
    • 檢查?popST?是否為空。若為空,需將?pushST?中元素轉移到?popST,以模擬隊列的先進先出。轉移過程:不斷獲取?pushST?棧頂元素(StackTop),壓入?popSTStackPush),再彈出?pushST?棧頂元素(StackPop)。
    • 轉移完成后,popST?棧頂即為隊列頭部元素,獲取該元素值(StackTop),彈出?popST?棧頂元素(StackPop),并返回元素值。

4.?myQueuePeek:獲取隊頭元素(取不刪)

int myQueuePeek(MyQueue* obj) {if (StackEmpty(&obj->popST)) {while (!StackEmpty(&obj->pushST)) {StackPush(&obj->popST, StackTop(&obj->pushST));StackPop(&obj->pushST);}}return StackTop(&obj->popST);
}

?

  • 功能:返回隊列頭部元素,不彈出。
  • 邏輯:與?myQueuePop?類似。先確保?popST?有元素(若?popST?空,轉移?pushST?元素),再通過?StackTop?獲取?popST?棧頂元素,即隊列頭部元素,不執行彈出操作。

5.?myQueueEmpty:判斷隊列是否為空

bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);
}

?

  • 功能:判斷隊列是否為空。
  • 原理:隊列由?pushST?和?popST?共同維護,只有兩者都為空時,隊列才為空。通過同時檢查兩個棧的?StackEmpty?狀態實現判斷。

6.?myQueueFree:釋放隊列資源

void myQueueFree(MyQueue* obj) {StackDestroy(&obj->pushST);StackDestroy(&obj->popST);free(obj);
}
  • 功能:釋放隊列及內部棧占用的內存。
  • 步驟
    • 先調用?StackDestroy?銷毀?pushST?和?popST?棧,釋放棧內部存儲元素的內存。
    • 最后釋放隊列結構體?obj?本身的內存,完成資源清理。

六、總結

通過兩個棧的巧妙配合,我們成功地實現了隊列的功能。這種實現方式不僅加深了我們對棧和隊列特性的理解,還展示了如何通過組合數據結構來解決實際問題。在實際編程中,靈活運用數據結構的特性可以讓我們更高效地解決各種問題。希望本文的解析能幫助讀者更好地掌握這一經典實現方法。

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

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

相關文章

前端如何導入谷歌字體庫

#谷歌字體庫內容豐富,涵蓋上千種多語言支持的字體,學習導入谷歌字體庫來增加網站的閱讀性,是必不可少的一項技能# 1,前往谷歌字體網站 要會魔法,裸連很卡 2, 尋找心儀字體 Googles Fonts下面的filters可…

SnapdragonCamera驍龍相機源碼解析

驍龍相機是高通開發的一個測試系統攝像頭的demo,代碼完善,功能強大。可以配合Camera驅動進行功能聯調。 很多邏輯代碼在CaptureModule.java里。 CaptureModule有8000多行,包羅萬象。 涉及到界面顯示要結合CaptureUI.java 一起來實現。 Ca…

多線程猜數問題

題目:線程 A 生成隨機數,另外兩個線程來猜數,線程 A 可以告訴猜的結果是大還是小,兩個線程都猜對后,游戲結束,編寫代碼完成。 一、Semaphore 多個線程可以同時操作同一信號量,由此實現線程同步…

seq2seq

理解 transformer 中的 encoder decoder 詳細的 transformer 教程見:【極速版 – 大模型入門到進階】Transformer 文章目錄 🌊 Encoder: 給一排向量輸出另外一排向量🌊 Encoder vs. Decoder: multi-head attention vs. masked multi-head at…

Proxmox pct 部署ubuntu

pct 前言 PCT(Proxmox Container Tool)是 PVE 中用于管理 Linux 容器(LXC)的命令行工具。通過 PCT,用戶可以執行各種容器管理任務,例如創建新的容器、啟動和停止容器、更新容器、安裝軟件包、導出和導入容器等。PCT 提供了與 Web 界面相同的功能,但通過命令行進行操作,…

Google Play關鍵字優化:關鍵排名因素與實戰策略

如果您準備發布應用程序或開始專注于關鍵字優化,您可能想知道如何向Google Play上的應用程序添加關鍵字。Google Play上的搜索量和排名與App Store不同,而且被索引排名的關鍵字也不同。在此文中,我們將確定Google Play上的關鍵排名因素&#…

Kafka延遲隊列實現分級重試

技術方案 方案背景 Kafka隊列消息消費處理過程中,發生處理異常,需要實現重試機制,并基于重試次數實現不同延遲時間重試方案。 方案介紹 通過實現Kafka延遲隊列來實現消息重試機制。 目標: 支持所有業務場景的延遲重試支持多…

Maven核心配置文件深度解析:pom.xml完全指南

🧑 博主簡介:CSDN博客專家、全棧領域優質創作者、高級開發工程師、高級信息系統項目管理師、系統架構師,數學與應用數學專業,10年以上多種混合語言開發經驗,從事DICOM醫學影像開發領域多年,熟悉DICOM協議及…

MSTP多域生成樹

協議信息 MSTP 兼容 STP 和 RSTP,既可以快速收斂,又提供了數據轉發的多個冗余路徑,在數據轉發過程中實現 VLAN 數據的負載均衡。 MSTP 可以將一個或多個 VLAN 映射到一個 Instance(實例)(一個或多個 VLAN…

MQTT 服務器(emqx)搭建及使用(一)

一. EMQX 服務器搭建 1.下載EMQX 下載鏈接:Windows | EMQX 文檔 官方手冊 2.下載內容解壓至盤符根目錄 3.進入bin文件夾,在地址欄輸入cmd 4.依次輸入下面命令安裝服務 .\emqx.cmd install .\emqx.cmd console 5.設置自啟動 創建批處理文件&#x…

在Thinkphp中使用JWT 包括JWT是什么,JWT的優勢

首先了解一下什么是JWT JWT 是一種開放標準(RFC 7519),用于在各方之間以 JSON 對象形式安全傳輸信息4。其核心特點包括: 結構:由三部分組成(Header、Payload、Signature),通過點號…

hackmyvn-casino

arp-scan -l nmap -sS -v 192.168.255.205 目錄掃描 dirsearch -u http://192.168.255.205/ -e * gobuster dir -u http://192.168.255.205 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php -b 301,401,403,404 80端口 隨便注冊一個賬號 玩游戲時的…

圖表配置表增加分析指標字段

在設計報表圖表配置表時,為存儲 同比、環比 這類分析指標,建議通過以下方式定義字段結構和命名: 一、字段設計方案 // 配置表示例結構 interface ChartConfig {id: string; // 唯一標識name: string; // 圖表…

廣州SMT貼片加工廠精密制造工藝解析

內容概要 在電子制造領域,SMT貼片加工技術已成為現代電子產品精密組裝的核心環節。廣州作為華南地區電子產業的重要樞紐,其SMT貼片加工廠通過融合自動化設備與嚴格工藝標準,構建起高效可靠的制造體系。 對于電子產品制造商而言,…

RK3568-適配ov5647攝像頭

硬件原理圖 CAM_GPIO是攝像頭電源控制引腳,連接芯片GPIO4_C2 CAM_LEDON是攝像頭led燈控制引腳,連接芯片GPIO4_C3編寫設備樹 / {ext_cam_clk: external-camera-clock {compatible = "fixed-clock";clock-frequency = <25000000>;clock-output-names = "…

關于 @Autowired 和 @Value 使用 private 字段的警告問題分析與解決方案

問題背景 在使用 Spring 框架進行開發時&#xff0c;我們經常會使用 Autowired 和 Value 注解來進行依賴注入和屬性值注入。然而&#xff0c;當我們將這些注解應用于 private 字段時&#xff0c;IDE&#xff08;如 IntelliJ IDEA&#xff09;可能會顯示警告信息&#xff0c;提…

Flutter 開發環境配置--宇宙級教學!

目錄 一、安裝環境&#xff08;Windows&#xff09;二、Android 創建Flutter項目三、VSCode 搭建環境四、補充 一、安裝環境&#xff08;Windows&#xff09; Flutter SDK 下載 推薦使用中國鏡像站點下載 Flutter SDK&#xff0c;速度更快&#xff1a;中國環境 或者從官網下載…

碰一碰發視頻網頁版本開發的源碼搭建指南

引言 在數字化信息快速傳播的時代&#xff0c;近場通信&#xff08;NFC&#xff09;技術為信息交互帶來了新的便捷方式。通過網頁版本實現碰一碰發視頻功能&#xff0c;能夠讓用戶在瀏覽器環境中輕松實現視頻分享&#xff0c;拓展了視頻傳播的途徑。本文將詳細介紹碰一碰發視頻…

OMNIWeb 數據介紹

網址&#xff1a;SPDF - OMNIWeb Service 注&#xff1a;OMNI并非特定縮寫&#xff0c;僅表示"多樣化"含義。 About the Data All the data to which this interface and its multiple underlying interfaces provide access have in common that they are relevan…

Python學習(二)操作列表

一、列表的遍歷 每個縮進的代碼行都是循環的一部分&#xff0c;且將針對列表中的每個值都執行一次。因此&#xff0c;可對列表中的每個值執行任意次數的操作。 magicians [alice, david, carolina] for magician in magicians:print(magician)注意&#xff1a; 1、遍歷的時…