[c語言日寄]數據結構:棧

在這里插入圖片描述

【作者主頁】siy2333
【專欄介紹】?c語言日寄?:這是一個專注于C語言刷題的專欄,精選題目,搭配詳細題解、拓展算法。從基礎語法到復雜算法,題目涉及的知識點全面覆蓋,助力你系統提升。無論你是初學者,還是進階開發者,這里都能滿足你的需求!
【食用方法】1.根據題目自行嘗試 2.查看基礎思路完善題解 3.學習拓展算法
【Gitee鏈接】資源保存在我的Gitee倉庫:https://gitee.com/siy2333/study


文章目錄

    • 前言:
    • 棧的基本概念
    • 棧的實現
      • 初始化
      • 入棧
      • 出棧
      • 查看棧頂元素
      • 檢查棧是否為空
      • 獲取棧的大小
      • 銷毀棧
    • 棧的應用場景
      • 函數調用
      • 表達式求值
      • 括號匹配
      • 瀏覽器的前進和后退功能
    • 棧的優缺點
    • 棧的優化
      • 預分配內存
      • 使用循環緩沖區
    • 棧的測試
    • 完整代碼
      • 頭文件
      • 源文件
    • 棧的總結


前言:

在計算機科學中,數據結構是組織和存儲數據的方式,而棧(Stack)是其中一種非常基礎且重要的數據結構。它遵循后進先出(Last In First Out,LIFO)的原則,就像一疊盤子,你只能在最上面添加或移除盤子。本文將深入探討棧的原理、實現方式以及應用場景,幫助讀者更好地理解和運用這一數據結構。

文末附帶完整的帶有標準注釋的c語言頭文件以及源文件


棧的基本概念

棧是一種線性數據結構,它只允許在表的一端進行插入和刪除操作。這一端被稱為棧頂(Top),而另一端被稱為棧底(Bottom)。棧的基本操作包括:

  1. 入棧(Push):將一個元素添加到棧頂。
  2. 出棧(Pop):移除棧頂的元素。
  3. 查看棧頂元素(Top):獲取棧頂元素的值,但不移除它。
  4. 檢查棧是否為空(Empty):判斷棧中是否還有元素。
  5. 獲取棧的大小(Size):返回棧中元素的數量。

這些操作的實現方式會因具體的編程語言和數據結構設計而有所不同,但基本原理是一致的。

棧的實現

棧可以通過數組或鏈表來實現。在本文中,我們將重點介紹基于數組的棧實現,因為它更簡單且易于理解。以下是基于數組的棧實現的關鍵點:

初始化

在使用棧之前,需要對其進行初始化。這通常包括分配內存空間、設置棧頂指針和棧的容量。在我們的代碼示例中,棧的初始化函數STInit會為棧分配初始容量為4的內存空間,并將棧頂指針設置為0。

void STInit(ST* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);if (ps->a == NULL){perror("malloc fail");return;}ps->capacity = 4;ps->top = 0; // The next position of the current stack top elementreturn;
}

入棧

當向棧中添加元素時,需要檢查棧是否已滿。如果棧已滿,則需要擴容。擴容通常是通過分配更大的內存空間來實現的。在我們的代碼中,當棧滿時,會將棧的容量加倍。

void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->capacity == ps->top){STDataType* point = (STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);if (point == NULL){perror("realloc fail");return;}ps->a = point;ps->capacity *= 2;}ps->a[ps->top] = x;ps->top++;return;
}

出棧

出棧操作相對簡單,只需要將棧頂指針減1即可。但在出棧之前,需要檢查棧是否為空,以避免出現錯誤。

void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;return;
}

查看棧頂元素

查看棧頂元素的操作也很簡單,只需要返回棧頂指針所指向的元素即可。同樣,在執行此操作之前,需要檢查棧是否為空。

STDataType STTop(ST* ps)
{assert(ps);assert(!STEmpty(ps));return ps->a[ps->top - 1];
}

檢查棧是否為空

檢查棧是否為空的操作可以通過比較棧頂指針是否為0來實現。

bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

獲取棧的大小

獲取棧的大小的操作可以通過返回棧頂指針的值來實現。

int STSize(ST* ps)
{assert(ps);return ps->top;
}

銷毀棧

在使用完棧后,需要對其進行銷毀,以釋放分配的內存空間。銷毀棧的操作包括釋放內存空間、將棧頂指針和容量設置為0。

void STDestory(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;return;
}

棧的應用場景

棧在計算機科學中有著廣泛的應用,以下是一些常見的應用場景:

函數調用

在編程語言中,函數調用是通過棧來實現的。當一個函數被調用時,它的參數、返回地址和局部變量等信息會被壓入調用棧中。當函數執行完畢后,這些信息會被彈出棧,程序會返回到調用函數的位置繼續執行。

表達式求值

棧可以用于表達式的求值。例如,在計算后綴表達式時,可以使用一個棧來存儲操作數。當遇到一個操作符時,從棧中彈出兩個操作數,進行相應的運算,然后將結果壓入棧中。當表達式計算完畢時,棧頂的元素就是表達式的值。

括號匹配

棧可以用于檢查括號是否匹配。當遇到一個左括號時,將其壓入棧中;當遇到一個右括號時,從棧中彈出一個左括號。如果在彈出左括號時棧為空,或者彈出的左括號與右括號不匹配,則說明括號不匹配。

瀏覽器的前進和后退功能

瀏覽器的前進和后退功能也可以通過棧來實現。當用戶訪問一個網頁時,將該網頁的地址壓入一個棧中;當用戶點擊后退按鈕時,從棧中彈出一個網頁地址并跳轉到該網頁;當用戶點擊前進按鈕時,將彈出的網頁地址壓入另一個棧中。

棧的優缺點

棧的優點包括:

  1. 簡單易用:棧的實現相對簡單,操作也容易理解。
  2. 高效:棧的基本操作(如入棧、出棧、查看棧頂元素等)的時間復雜度為O(1)。
  3. 適用范圍廣:棧在計算機科學中有著廣泛的應用,如函數調用、表達式求值、回溯算法等。

然而,棧也有一些缺點:

  1. 容量限制:如果棧的容量有限,可能會出現棧溢出的情況。雖然可以通過動態擴容來解決這個問題,但動態擴容會增加時間和空間的開銷。
  2. 只能在一端操作:棧只能在棧頂進行插入和刪除操作,不能在其他位置進行操作。

棧的優化

雖然棧的基本操作已經非常高效,但在某些情況下,我們仍然可以通過一些優化手段來提高棧的性能。以下是一些常見的優化方法:

預分配內存

在初始化棧時,可以預分配一定量的內存空間,以減少動態擴容的次數。這可以提高棧的性能,但會增加內存的使用量。

使用循環緩沖區

循環緩沖區是一種特殊的數組結構,它可以循環使用內存空間。通過使用循環緩沖區,可以減少內存的分配和釋放次數,從而提高棧的性能。

棧的測試

為了驗證棧的正確性和性能,我們需要對其進行測試。以下是一個簡單的測試程序,用于測試棧的基本操作:

#include"Stack.h"void Test1()
{ST head;STInit(&head);STPush(&head, 1);STPush(&head, 2);STPush(&head, 3);STPush(&head, 4);STPush(&head, 5);while (!STEmpty(&head)){printf("%d ", STTop(&head));STPop(&head);}printf("\n");return;
}int main()
{Test1();return 0;
}

在這個測試程序中,我們首先初始化了一個棧,然后依次向棧中添加了5個元素。接著,我們依次從棧中彈出元素,并打印出每個元素的值。最后,我們銷毀了棧。

完整代碼

頭文件

#pragma once/**
* @file Stack.h
* @brief The header file of the Stack.
* @author siy2333
* @date 2025.5.11
*
* This header file defines the data structure and related operation functions of a Stack.
* Stack is a Last-In-First-Out (LIFO) data structure used for storing and managing data elements, supporting operations to add (push) and remove (pop) elements at the top, and is widely applied in program calling, expression evaluation, and other scenarios.
* Provides basic operations for adding, deleting, querying, and modifying.
*///Standard library header files included.
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>/**
* @brief The data types stored in the Stack.
*/
typedef int STDataType;/**
* @typedef struct Stack.
* @brief Structure definition of Stack.
*/
typedef struct Stack
{STDataType* a;		///< The pointer to the memory for the Stack.int top;			///< The next position of the current Stack top element.int capacity;		///< The size of capacity.
}ST;/**
* @brief Initialize Stack.
*/
void STInit(ST* ps);/**
* @brief Destory the Stack.
*/
void STDestory(ST* ps);/**
* @brief Store x in the top of the Stack.
*/
void STPush(ST* ps, STDataType x);/**
* @brief Delete x at the top of the Stack.
*/
void STPop(ST* ps);/**
* @brief return the capacity size of the Stack.
*/
int STSize(ST* ps);/**
* @brief Check whether the Stack is empty.
* @return If the Stack is empty, return 1; Otherwise, return 0.
*/
bool STEmpty(ST* ps);/**
* @brief Return the data at the top of the Stack.
* @return the data at the top of the Stack.
*/
STDataType STTop(ST* ps);

源文件

#include"Stack.h"/**
* @detailsThe faction use malloc to apply for 4 copies of memory for the Stack.The 0 will be store int the ps->top, it mean the next position of the current stack top element.The capacity will be set to 4.
* @warning ps mustn't be NULL.
*/
void STInit(ST* ps)
{assert(ps);ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);if (ps->a == NULL){perror("malloc fail");return;}ps->capacity = 4;ps->top = 0;		//The next position of the current stack top elementreturn;
}/**
* @details The faction will free the memory for the Stack;The top will be set to 0;The capacity will be set to 0.
* @warning ps mustn't be NULL.
*/
void STDestory(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = 0;ps->capacity = 0;return;
}/**
* @details The faction will check whether the Stack is full;If the Stack is full, it will use realloc() to double the capacity, and refresh the ps->capacity.It will store the x in the ps->a[top], and refresh the ps->top.
* @warning ps mustn't be NULL.
*/
void STPush(ST* ps, STDataType x)
{assert(ps);if (ps->capacity == ps->top){STDataType* point = (STDataType*)realloc(ps->a,sizeof(STDataType) * ps->capacity * 2);if (point == NULL){perror("realloc fail");return;}ps->a = point;ps->capacity *= 2;}ps->a[ps->top] = x;ps->top++;return;
}/**
* @details The function will refresh the ps->top.
* @warning ps musn't be NULL;
* @warning The Stack mustn't be empty.
*/
void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->top--;return;
}/**
* @warning ps mustn't be NULL;
*/
int STSize(ST* ps)
{assert(ps);return ps->top;
}/**
* @warning ps mustn't be NULL;
*/
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}/**
* @warning ps musn't be NULL;
* @warning The Stack mustn't be empty.
*/
STDataType STTop(ST* ps)
{assert(ps);assert(!STEmpty(ps));return ps->a[ps->top - 1];
}

棧的總結

棧是一種非常基礎且重要的數據結構,它遵循后進先出的原則。棧的基本操作包括入棧、出棧、查看棧頂元素、檢查棧是否為空和獲取棧的大小等。棧可以通過數組或鏈表來實現,其中基于數組的棧實現相對簡單且易于理解。棧在計算機科學中有著廣泛的應用,如函數調用、表達式求值、回溯算法等。雖然棧有一些缺點,但它的優點使其在許多場景下都非常有用。通過一些優化手段,我們可以進一步提高棧的性能。總之,棧是一種非常重要的數據結構,值得我們深入學習和研究。

希望本文對您理解棧有所幫助。如果您有任何問題或建議,歡迎在評論區留言討論。

[專欄鏈接QwQ] :?c語言日寄?CSDN
[關注博主ava]:siy2333
感謝觀看~ 我們下次再見!!

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

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

相關文章

磁盤I/O瓶頸排查:面試通關“三部曲”心法

想象一下&#xff0c;你就是線上系統的“交通調度總指揮”&#xff0c;服務器的磁盤是所有數據進出的“核心樞紐港口”。當這個“港口”突然擁堵不堪&#xff0c;卡車&#xff08;數據請求&#xff09;排起長龍&#xff0c;進不去也出不來&#xff0c;整個系統的“物流”&#…

基于大模型預測胃穿孔預測與圍手術期管理系統技術方案

目錄 1. 系統架構模塊2. 關鍵算法實現2.1 術前預測模型(Transformer多模態融合)2.2 術中實時分析(在線學習LSTM)3. 模塊流程圖(Mermaid)3.1 數據預處理系統3.2 術前預測系統3.3 術中實時分析系統4. 技術驗證模塊4.1 模型可解釋性驗證4.2 邊緣計算部署架構1. 系統架構模塊…

C++:類和對象4

一&#xff0c;日期類實現 學習建議&#xff1a; 對于計算機學習來說&#xff0c;調試十分重要&#xff0c;所以在日常學習中一定要加大代碼練習&#xff0c;刷代碼題和課后自己敲出課上代碼例題&#xff0c;注意不要去對比正確代碼或者網上找正確代碼直接使用&#xff0c;一…

大數據架構選型分析

選擇依據 1.業務需求與技術要求 用戶需要根據自己的業務需求來選擇架構&#xff0c;如果業務對于Hadoop、Spark、Strom等關鍵技術有強制性依賴&#xff0c;選擇Lambda架構可能較為合適&#xff1b;如果處理數據偏好于流式計算&#xff0c;又依賴Flink計算引擎&#xff0c;那么…

Trae 插件 Builder 模式:從 0 到 1 開發天氣查詢小程序,解鎖 AI 編程新體驗

在軟件開發領域&#xff0c;效率與創新始終是開發者追求的核心目標。Trae 插件&#xff08;原 MarsCode 編程助手&#xff09;Builder 模式的全面上線&#xff0c;無疑為開發者帶來了全新的解決方案。它不僅同時支持 VS Code、JetBrains IDEs 等主流開發環境&#xff0c;還能讓…

SSM項目集成redis、Linux服務器安裝redis

在SSM&#xff08;Spring Spring MVC MyBatis&#xff09;項目中引入Redis主要分為以下步驟&#xff0c;確保配置正確并能在業務中靈活使用&#xff1a; 1. 添加Redis依賴?? 在Maven的pom.xml中添加Spring Data Redis和Jedis&#xff08;或Lettuce&#xff09;依賴&#…

【Redis】壓縮列表

目錄 1、背景2、壓縮列表【1】底層結構【2】特性【3】優缺點 1、背景 ziplist&#xff08;壓縮列表&#xff09;是redis中一種特殊編碼的雙向鏈表數據結構&#xff0c;主要用于存儲小型列表和哈希表。它通過緊湊的內存布局和特殊的編碼方式來節省內存空間。 2、壓縮列表 【1…

LocalDateTime類型的時間在前端頁面不顯示或者修改數據時因為LocalDateTime導致無法修改,解決方案

1.數據庫中的時間數據&#xff0c;在控制臺可以正常返回&#xff0c;在前端無法返回&#xff0c;即顯示空白&#xff0c;如下圖所示: 2.這種問題一般時由于數據庫和我們實體類的名稱不一致引起的&#xff0c;我們數據庫一般采用_的方式命名&#xff0c;但是在Java中我們一般采用…

Spring框架核心技術深度解析:JDBC模板、模擬轉賬與事務管理

一、JDBC模板技術&#xff1a;簡化數據庫操作 在傳統JDBC開發中&#xff0c;繁瑣的資源管理和重復代碼一直是開發者的痛點。Spring框架提供的 JDBC模板&#xff08;JdbcTemplate) 徹底改變了這一現狀&#xff0c;它通過封裝底層JDBC操作&#xff0c;讓開發者僅需關注SQL邏輯&a…

Modern C++(一)基本概念

1、基本概念 1.1、注釋 注釋在翻譯階段3會被替換為單個空白字符從程序中移除 1.2、名字與標識符 標識符是一個由數字、下劃線、大小寫字符組成的任意長度序列。有效的標識符首個字符必須是以A-Z、a-z、下劃線開頭&#xff0c;。有效的標識符其他字符可以是0-9、A-Z、a-z、下…

STM32的TIMx中Prescaler和ClockDivision的區別

Prescaler預分頻&#xff0c;以筆者目前的學習程度來說&#xff0c;這個參數&#xff0c;一般來說是對主時鐘進行分頻后的計數器時鐘。這個預分頻后的時鐘主要是用于的計數的。 這個主時鐘&#xff0c;對于時基單元來說可以是內部時鐘&#xff0c;也可以是外部時鐘。一般來說我…

前端性能指標及優化策略——從加載、渲染和交互階段分別解讀詳解并以Webpack+Vue項目為例進行解讀

按照加載階段、渲染階段和交互階段三個維度進行系統性闡述&#xff1a; 在現代 Web 開發中&#xff0c;性能不再是錦上添花&#xff0c;而是決定用戶體驗與業務成敗的關鍵因素。為了全面監控與優化網頁性能&#xff0c;我們可以將性能指標劃分為加載階段、渲染階段、和交互階段…

MySQL——1、數據庫基礎

數據庫基礎 1、安裝MySQL2、什么是數據庫3、數據庫使用案例4、MySQL架構與SQL分類5、存儲引擎 1、安裝MySQL 1、更新軟件包列表 sudo apt update2、查看MySQL安裝包 apt list | grep mysql-server3、安裝MySQL # 默認安裝最新版 sudo apt install -y mysql-server4、啟動My…

ET MailBoxComponent類(實體) 分析

MailBoxComponent 作用是&#xff0c;用來接收Actor消息&#xff0c;處理Actor消息。這個沒有存儲能&#xff0c;收到消息后立即就處理了。ParentInstanceId 是MailBox所在的實體InstanceIdMailBoxType MailBox類型MailBoxInvoker 分發消息的包裝Add 方法&#xff0c;看名字是…

Weblogic SSRF漏洞復現(CVE-2014-4210)【vulhub靶場】

漏洞概述&#xff1a; Weblogic中存在一個SSRF漏洞&#xff0c;利用該漏洞可以發送任意HTTP請求&#xff0c;進而攻擊內網中redis、fastcgi等脆弱組件。 漏洞形成原因&#xff1a; WebLogic Server 的 UDDI 組件&#xff08;uddiexplorer.war&#xff09;中的 SearchPublicR…

js應用opencv

思路&#xff1a; 第一步&#xff1a;直方圖 第二步&#xff1a;獲得直方圖的波峰 第三步&#xff1a;波峰勝負10&#xff0c;高于或低于變紅色 1.引用import cv from ‘techstark/opencv-js’; 2.vue代碼 <div class"historyLeft2"><div style"relat…

用Python代碼繪制動態3D愛心效果

引言 介紹Python在創意編程中的應用&#xff0c;特別是如何通過簡單的代碼實現視覺上的美感。引出本文將分享的愛心代碼&#xff0c;并簡要說明其實現原理。 愛心代碼的基本實現 展示一個簡單的Python代碼示例&#xff0c;使用字符畫的方式在控制臺中繪制一個愛心圖案。 pr…

使用Python開發經典俄羅斯方塊游戲

使用Python開發經典俄羅斯方塊游戲 在這篇教程中&#xff0c;我們將學習如何使用Python和Pygame庫開發一個經典的俄羅斯方塊游戲。這個項目將幫助你理解游戲開發的基本概念&#xff0c;包括圖形界面、用戶輸入處理、碰撞檢測等重要內容。 項目概述 我們將實現以下功能&…

兼顧長、短視頻任務的無人機具身理解!AirVista-II:面向動態場景語義理解的無人機具身智能體系統

作者&#xff1a;Fei Lin 1 ^{1} 1, Yonglin Tian 2 ^{2} 2, Tengchao Zhang 1 ^{1} 1, Jun Huang 1 ^{1} 1, Sangtian Guan 1 ^{1} 1, and Fei-Yue Wang 2 , 1 ^{2,1} 2,1單位&#xff1a; 1 ^{1} 1澳門科技大學創新工程學院工程科學系&#xff0c; 2 ^{2} 2中科院自動化研究所…

【藍橋杯省賽真題49】python偶數 第十五屆藍橋杯青少組Python編程省賽真題解析

python偶數 第十五屆藍橋杯青少組python比賽省賽真題詳細解析 博主推薦 所有考級比賽學習相關資料合集【推薦收藏】1、Python比賽 信息素養大賽Python編程挑戰賽 藍橋杯python選拔賽真題詳解