棧概念和結構

文章目錄

  • 1. 棧的概念
  • 2. 棧的分類
  • 3. 棧的實現(數組棧)
    • 3.1 接口設計(Stack.h)
    • 3.2 接口實現(Stack.c)
      • 1)初始化銷毀
      • 2)棧頂插入刪除
      • 3)棧頂元素、空棧、大小
    • 3.3 完整代碼
      • Stack.h
      • Stack.c
      • test.c
      • 注意:
      • 運行效果

1. 棧的概念

棧:一種特殊的線性表,其只允許在固定的一端進行插入和刪除元素操作。 進行數據插入和刪除操作的一端稱為棧頂,另一端稱為棧底。 棧中的數據元素遵守后進先出LIFO(Last In First Out)的原則。
壓棧:棧的插入操作叫做進棧/壓棧/入棧,入數據在棧頂
出棧:棧的刪除操作叫做出棧,出數據也在棧頂

遵循的原則是:后進先出

結構概念

2. 棧的分類

棧的實現有3種方式

2.1 數組棧:棧底是數組頭,棧頂是數組尾。

數組棧

2.2 鏈式棧:

1)雙向鏈表實現: 棧頂可以是尾也可以是頭

2)單向鏈表實現: 棧頂只能是頭(開銷小)

鏈表棧

棧的實現一般可以使用以上方式實現,相對而言數組的結構實現更優一些。因為數組在尾上插入數據的代價比較小。

3. 棧的實現(數組棧)

下面將其分為3個模塊進行實現Stack.h,Stack.c,test.c

3.1 接口設計(Stack.h)

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int STDataType;typedef struct Stack
{STDataType *a;//這里是可以指向棧頂的,那下面的寫法就要做對應修改int top;		//這里則是標識棧頂位置下一個int capacity;
}ST;//初始化銷毀擴容
void STInit(ST* pst);
void STDestroy(ST* pst);
void CheckCapacity(ST* pst);
//棧頂插入刪除
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
//棧頂元素、空棧、大小
STDataType STTop(ST* pst);
bool STEmpty(ST* pst);
int STSize(ST* pst);

3.2 接口實現(Stack.c)

1)初始化銷毀

這里需要討論一些 top 的指向問題:

如果 top 指向棧頂元素位置,則初始化時 top = -1 ;這時要push時要先對 top ++后賦值。

如果 top 指向棧頂元素下一個位置,則初始化時 top == 0 ;這時要push時要先對 top 賦值后++。

這里采用第二種寫法。

void STInit(ST* pst)
{assert(pst);pst->a = NULL;pst->capacity = 0;這里初始化為-1,表示指向棧頂元素//pst->top = 0;//這里初始化為0,表示指向棧頂下一個元素pst->top = 0;
}void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->top = pst->capacity = 0;
}

2)棧頂插入刪除

刪除這里要判斷 top > 0 ,和結構定義一致

void STCheckCapacity(ST* pst)
{if (pst->capacity == pst->top){int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));if (tmp == NULL){perror("relloc fail\n");exit(-1);}pst->a = tmp;pst->capacity = newCapacity;}
}void STPush(ST* pst, STDataType x)
{assert(pst);STCheckCapacity(pst);pst->a[pst->top++] = x;
}void STPop(ST* pst)
{assert(pst);//不為空assert(pst->top > 0);pst->top--;
}

3)棧頂元素、空棧、大小

在判斷空棧有個小技巧:即直接返回判斷語句即可,因為他們的結果也是對或錯

STDataType STTop(ST* pst)
{assert(pst);//不為空assert(pst->top > 0);return pst->a[pst->top - 1];
}bool STEmpty(ST* pst)
{assert(pst);1//if (pst->top == 0)//{//	return true;//}//else//{//	return false;//}2//return pst->top == 0 ? true : false;//3return pst->top == 0;
}int STSize(ST* pst)
{assert(pst);return pst->top;
}

3.3 完整代碼

Stack.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int STDataType;typedef struct Stack
{STDataType *a;int top;		//標識棧頂位置int capacity;
}ST;//初始化銷毀
void STInit(ST* pst);
void STDestroy(ST* pst);
void STCheckCapacity(ST* pst);
//棧進棧出
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
//棧頂元素、空棧、大小
STDataType STTop(ST* pst);
bool STEmpty(ST* pst);
int STSize(ST* pst);

Stack.c

#include "Stack.h"//初始化銷毀
void STInit(ST* pst)
{assert(pst);pst->a = NULL;pst->capacity = 0;這里初始化為-1,表示指向棧頂元素//pst->top = 0;//這里初始化為0,表示指向棧頂下一個元素pst->top = 0;
}void STDestroy(ST* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->top = pst->capacity = 0;
}void STCheckCapacity(ST* pst)
{if (pst->capacity == pst->top){int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));if (tmp == NULL){perror("relloc fail\n");exit(-1);}pst->a = tmp;pst->capacity = newCapacity;}
}//棧進棧出
void STPush(ST* pst, STDataType x)
{assert(pst);STCheckCapacity(pst);pst->a[pst->top++] = x;
}void STPop(ST* pst)
{assert(pst);//不為空assert(pst->top > 0);pst->top--;
}//棧頂元素、空棧、大小
STDataType STTop(ST* pst)
{assert(pst);//不為空assert(pst->top > 0);return pst->a[pst->top - 1];
}bool STEmpty(ST* pst)
{assert(pst);1//if (pst->top == 0)//{//	return true;//}//else//{//	return false;//}2//return pst->top == 0 ? true : false;//3return pst->top == 0;
}int STSize(ST* pst)
{assert(pst);return pst->top;
}

test.c

#include "Stack.h"void STTest()
{ST s;STInit(&s);STPush(&s, 1);STPush(&s, 2);STPush(&s, 3);STPush(&s, 4);STPush(&s, 5);STPush(&s, 6);STPush(&s, 7);STPush(&s, 8);STPush(&s, 9);printf("棧頂元素是 %d, 棧個數為 %d\n", STTop(&s), STSize(&s));//訪問棧只能先打印棧頂,然后出棧,然后繼續訪問//入棧順序和出棧順序是一對多的關系printf("打印棧全部元素: \n");while (!STEmpty(&s)){printf("%d ", STTop(&s));STPop(&s);}printf("\n");printf("銷毀棧\n");STDestroy(&s);
}int main()
{STTest();return 0;
}

注意:

1)訪問棧只能先打印棧頂,然后出棧,然后繼續訪問,訪問完成棧也就為空了
2)入棧順序和出棧順序是一對多的關系,判斷順序可以模擬過程就能判斷哪種順序是錯的

運行效果

棧運行結果

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

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

相關文章

GitCode 助力 vue3-element-admin:開啟中后臺管理前端開發新征程

源碼倉庫&#xff1a; https://gitcode.com/youlai/vue3-element-admin 后端倉庫&#xff1a; https://gitcode.com/youlai/youlai-boot 開源助力&#xff0c;開啟中后臺快速開發之旅 vue3-element-admin 是一款精心打造的免費開源中后臺管理前端模板&#xff0c;它緊密貼合…

算法.習題篇

算法 — 地大復試 模擬 while循環和MOD循環計數 1.約瑟夫問題 http://bailian.openjudge.cn/practice/3254 using namespace std;bool isNoPeople(vector<bool> c)//判斷當前數組是否一個小孩都沒有了 {bool nopeople true;for (bool ival : c){if ( ival true)nop…

大白話JavaScript實現一個函數,將字符串中的每個單詞首字母大寫。

大白話JavaScript實現一個函數&#xff0c;將字符串中的每個單詞首字母大寫。 答題思路 理解需求&#xff1a;要寫一個函數&#xff0c;它能接收一個字符串&#xff0c;然后把這個字符串里每個單詞的第一個字母變成大寫。分解步驟 拆分單詞&#xff1a;一般單詞之間是用空格隔…

react中如何使用使用react-redux進行數據管理

以上就是react-redux的使用過程&#xff0c;下面我們開始優化部分&#xff1a;當一個組件只有一個render生命周期&#xff0c;那么我們可以改寫成一個無狀態組件&#xff08;UI組件到無狀態組件&#xff0c;性能提升更好&#xff09;

廣告營銷,會被AI重構嗎?

DeepSeek設計&#xff0c;即夢AI繪圖&#xff0c;剪映成片。 DeepSeek的熱度還在高開瘋走。 用戶對于各個場景下DS應用的探索也還在持續&#xff0c;各種DS的模式被挖掘出來&#xff0c;超級個體們開始給手下的大模型團隊進行分工&#xff0c;實踐出各種場景下最佳的排列組合方…

國產編輯器EverEdit - 宏功能介紹

1 宏 1.1 應用場景 宏是一種重復執行簡單工作的利器&#xff0c;可以讓用戶愉快的從繁瑣的工作中解放出來&#xff0c;其本質是對鍵盤和菜單的操作序列的錄制&#xff0c;并不會識別文件的內容&#xff0c;屬于無差別無腦執行。 特別是對一些有規律的重復按鍵動作&#xff0c;…

vscode離線配置遠程服務器

目錄 一、前提 二、方法 2.1 查看vscode的commit_id 2.2 下載linux服務器安裝包 2.3 安裝包上傳到遠程服務器&#xff0c;并進行文件解壓縮 三、常見錯誤 Failed to set up socket for dynamic port forward to remote port&#xff08;vscode報錯解決方法&#xff09;-C…

OmniDrive(1): 論文解讀

多模態大語言模型(MLLMs)的發展推動了基于 LLM 的自動駕駛研究,以利用其強大的推理能力。然而,利用多模態大語言模型(MLLMs)強大的推理能力來改進planning具有挑戰性,因為這需要超越二維推理的完整三維情境感知能力。因為這不單單需要 2D 推理還需要完整的 3D 場景感知能…

ubuntu22.04安裝RAGFlow配合DeepSeek搭建本地知識庫

一、簡介 RAGFlow 是一個基于對文檔的深入理解的開源 RAG&#xff08;檢索增強生成&#xff09;引擎。當與 LLM 集成時&#xff0c;它能夠提供真實的問答功能&#xff0c;并以來自各種復雜格式數據的有根據的引用為后盾。 二、安裝 1.環境要求 CPU ≥ 4 核 &#xff08;x86…

Android AudioFlinger(四)—— 揭開PlaybackThread面紗

前言&#xff1a; 繼上一篇Android AudioFlinger&#xff08;三&#xff09;—— AndroidAudio Flinger 之設備管理我們知道PlaybackThread繼承自Re’fBase&#xff0c; 在被第一次引用的時候就會調用onFirstRef&#xff0c;實現如下&#xff1a; void AudioFlinger::Playbac…

個人電腦本地部署DeepSeek來離線使用

文章目錄 前言軟件下載DeepSeek部署ChatBox集成 前言 最近這段時間&#xff0c;“DeepSeek”&#xff08;深度求索&#xff09;人工智能平臺非常的火爆&#xff0c;正確的使用可以幫我們做很多很多事情&#xff0c;通常我們是在瀏覽器網頁或手機APP使用&#xff0c;但是有時會…

第一:goland安裝

GOPROXY (會話臨時性)&#xff0c;長久的可以在配置文件中配置 go env -w GOPROXYhttps://goproxy.cn,direct 長久的&#xff0c;在~/.bashrc文件中添加&#xff1a; export GOPROXYhttps://goproxy.cn,direct &#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d…

介紹一下Qt中的事件過濾

在 Qt 中&#xff0c;事件過濾&#xff08;Event Filter&#xff09;是一種強大的機制&#xff0c;它允許一個對象攔截并處理另一個對象接收到的事件。通過事件過濾&#xff0c;可以在事件到達目標對象之前對其進行監控和修改&#xff0c;這在很多場景下都非常有用&#xff0c;…

Go紅隊開發—格式導出

文章目錄 輸出功能CSV輸出CSV 轉 結構體結構體 轉 CSV端口掃描結果使用CSV格式導出 HTML輸出Sqlite輸出nmap掃描 JSONmap轉json結構體轉jsonjson寫入文件json編解碼json轉結構體json轉mapjson轉string練習&#xff1a;nmap掃描結果導出json格式 輸出功能 在我們使用安全工具的…

SwanLab簡明教程:從萌新到高手

目錄 1. 什么是SwanLab&#xff1f; 1.1 核心特性 2. 安裝SwanLab 3. 登錄SwanLab賬號&#xff08;云端版&#xff09; 4. 5分鐘快速上手 更多案例 5. SwanLab功能組件 5.1 圖表視圖 5.2 表格視圖 5.3 硬件監控 5.4 環境記錄 5.5 組織協同 6. 訓練框架集成 6.1 基…

2025天梯訓練1

PTA | L3-1 直搗黃龍 30分 思路&#xff1a;多關鍵字最短路&#xff0c;同時還要記錄最短路徑條數。 typedef struct node{int from,d,pass,kl;bool operator<(const node &x)const{if(d!x.d) return d>x.d;if(pass!x.pass) return pass<x.pass;return kl<x.…

EasyRTC嵌入式視頻通話SDK的跨平臺適配,構建web瀏覽器、Linux、ARM、安卓等終端的低延遲音視頻通信

1、技術背景 WebRTC是一項開源項目&#xff0c;旨在通過簡單的API為瀏覽器和移動應用程序提供實時通信&#xff08;RTC&#xff09;功能。它允許在無需安裝插件或軟件的情況下&#xff0c;實現點對點的音頻、視頻和數據傳輸。 WebRTC由三個核心組件構成&#xff1a; GetUserM…

【git】ssh配置提交 gitcode-ssh提交

【git】ssh配置提交 gitcode-ssh提交 之前一直用的是gitee和阿里云的倉庫&#xff0c;前兩天想在gitcode上面備份一下我的打洞代碼和一些資料 就直接使用http克隆了下來 。 在提交的時候他一直會讓我輸入賬號和密碼&#xff0c;但是我之前根本沒有設置過這個&#xff0c;根本沒…

Dify部署踩坑指南(Windows+Mac)

組件說明 Dify踩坑及解決方案 ?? 除了修改鏡像版本&#xff0c;nginx端口不要直接修改docker-compose.yaml &#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 1、更換鏡像版本 這個文件是由.env自動生成的&#xff0c;在.env配置 …

Linux進程調度與管理:(五)進程的調度之調度節拍

《Linux6.5源碼分析&#xff1a;進程管理與調度系列文章》 本系列文章將對進程管理與調度進行知識梳理與源碼分析&#xff0c;重點放在linux源碼分析上&#xff0c;并結合eBPF程序對內核中進程調度機制進行數據實時拿取與分析。 在進行正式介紹之前&#xff0c;有必要對文章引…