數據結構入門:棧

目錄

前言

1. 棧

1.1棧的概念及結構

?1.2 棧的實現

1.2.1 棧的定義

?1.2.2? 棧的初始化

1.2.3 入棧

1.2.4 出棧

1.2.5? 棧的元素個數

1.2.6 棧頂數據

1.2.7 棧的判空

?2.棧的應用

?2.1 題目一:括號匹配

2.1.1 思路

?2.1.2 分析

?2.1.3 題解

總結


前言

????????無論你是計算機科學專業的學生、程序設計的愛好者,還是正在準備面試的求職者,本文將為你提供一份全面而深入的棧和隊列指南。讓我們一起探索棧和隊列的雙重魅力,為你的編程之路增添新的色彩。


1. 棧

1.1棧的概念及結構

棧:一種特殊的線性表,其只允許在固定的一端進行插入和刪除元素操作。進行數據插入和刪除操作的一端稱為棧頂,另一端稱為棧底

棧中的數據元素遵守后進先出LIFO(Last In First Out)的原則。

  • 壓棧:棧的插入操作叫做進棧/壓棧/入棧,入數據在棧頂。
  • 出棧:棧的刪除操作叫做出棧。出數據也在棧頂。

?

?1.2 棧的實現

????????棧的實現方法有兩種,一種是順序表的棧,另外一種就是鏈表實現的棧。相對而言數組的結構實現更優一些。因為數組在尾上插入數據的代價比較小,所以這里我們使用順序表來實現棧。

?????????如果熟練順序表和鏈表操作,那棧就會相當輕松,棧的入棧出棧就相當于是尾插尾刪,順序表尾插尾刪的效率高,這也是使用順序表實現的原因。

1.2.1 棧的定義

首先我們需要先定義一個棧:

typedef int Datatype;
typedef struct Stack
{Datatype* a;int top;int capacity;
}Stack;

?棧中有棧頂(top),有棧的容量(size),還有存儲的數據(a);

?1.2.2? 棧的初始化

?

void InItStack(Stack* ps)
{assert(ps);ps->top = 0;ps->a = NULL;ps->capacity = 0;
}

?????????這里對棧進行初始化時棧頂(top)可以置為-1,也可以置為0,置為0為了便于使用top作為數組下標插入數據。

1.2.3 入棧

????????棧已經定義完成并且進行了初始化,接下來就是入棧操作。這里與順序表的尾插略微有些不同。

void StackPush(Stack* ps, Datatype x)
{assert(ps);if (ps->top == ps->capacity){int newcapacity = (ps->capacity == 0 ? 4 : ps->capacity * 2);Datatype* tmp = (Datatype*)realloc(ps->a, sizeof(Datatype) * newcapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;//top初始化為0,可以直接作為數組下標ps->top++;//入棧后top++,便于統計元素個數和下次入棧
}

????????由于我們初始化時將棧的容量置為0,在這里我們在入棧操作時就需要進行開辟空間,但這里如果我們使用malloc開辟空間,就還需要進行擴容操作,所以我們直接使用realloc進行開辟空間。

?realloc在擴容時,如果原始區域空間為0,那么它的作用就類似于malloc。

?????????此外我們還需要有新開辟空間的大小,這里我們直接使用一個判斷語句:newsize = (ps->size == 0 ? 4 : ps->size * 2);? 如果size等于0就開辟4個存儲數據的空間,如果不等于0就直接擴容為2倍。

1.2.4 出棧

?出棧操作就很簡單了,也不需要銷毀,直接進行top--:

void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}

????????但我們需要注意棧為空的情況,所有使用assert強制檢查,如果為空直接報錯終止程序,簡單粗暴。

1.2.5? 棧的元素個數

統計棧的元素個數接口也很簡單,top就是棧中元素的個數

int Stacksize(Stack* ps)
{assert(ps);return ps->top;
}

1.2.6 棧頂數據

Datatype TopData(Stack* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}

這個也非常簡單,需要注意棧為空的情況。

1.2.7 棧的判空

bool IsEmpty(Stack* ps)
{assert(ps);return (ps->top == 0);
}

?2.棧的應用

?????????這些棧的基本操作我們已經實現了,接下來我們來實際應用一下。雖然棧的基本操作更為簡單,但是棧在應用時數據的結構更加復雜,前邊的順序表和鏈表是棧和隊列的基礎。

?2.1 題目一:括號匹配

????????這道題目我們可以使用數組實現并解決,但我們已經了解了棧,這道題目我們就使用順序表棧來實現。我們可以直接復制上述棧基本操作的代碼。將?typedef? int? Datatype;

?改為:typedef? char? Datatype;

題目描述:

?示例:

?題目鏈接:

有效括號

2.1.1 思路

?????????這道題目的思路很明確,入棧左括號,遇到匹配的右括號就出棧。如果最終棧為空就匹配成功。但匹配失敗的情況有很多,接下來我們進行逐個分析。

?2.1.2 分析

? ? ? ? ?首先是入棧,如果為左括號就入棧,為右括號就匹配出棧。這里使用if…else語句更為簡潔,入棧就需要我們調用入棧的函數接口。

? ? ? ? 其次就是匹配、出棧。但在匹配之前我們還需要考慮特殊情況,就是如果沒有出棧元素就直接匹配的情況,所以首先我們需要有一個判空操作,如果匹配時棧就為空就直接匹配失敗,并銷毀棧,這個屬于左括號與右括號數量匹配失敗。

? ? ? ? ?接著就是順序匹配失敗,這里就需要我們用到棧頂元素了,如果棧頂元素與匹配的括號不匹配就直接返回false,匹配失敗,銷毀棧。

? ? ? ? 最后,匹配結束,存放括號數組為空,棧也為空就匹配成功。

?2.1.3 題解

匹配括號接口:

bool isValid(char* s) {Stack st;InItStack(&st);char top;while (*s){if (*s == '(' || *s == '[' || *s == '{'){StackPush(&st, *s);}else{if(IsEmpty(&st)){DestoryStack(&st);return false;}top=TopData(&st);StackPop(&st);if((*s==']'&&top!='[')||(*s==')'&&top!='(')||(*s=='}'&&top!='{')){DestoryStack(&st);return false;}}s++;}bool ret = IsEmpty(&st);DestoryStack(&st);return ret;
}

整體代碼:

typedef char Datatype;
typedef struct Stack
{Datatype* a;int top;int size;
}Stack;void InItStack(Stack* ps);void DestoryStack(Stack* ps);void StackPush(Stack* ps, Datatype x);void StackPop(Stack* ps);int Stacksize(Stack* ps);Datatype TopData(Stack* ps);bool IsEmpty(Stack* ps);void InItStack(Stack* ps)
{assert(ps);ps->top = 0;ps->a = NULL;ps->size = 0;
}void DestoryStack(Stack* ps)
{assert(ps);ps->top = ps->size = 0;free(ps->a);ps->a = NULL;
}
void StackPush(Stack* ps, Datatype x)
{assert(ps);if (ps->top == ps->size){int newsize = (ps->size == 0 ? 4 : ps->size * 2);Datatype* tmp = (Datatype*)realloc(ps->a, sizeof(Datatype) * newsize);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->size = newsize;}ps->a[ps->top] = x;ps->top++;
}
void StackPop(Stack* ps)
{assert(ps);assert(ps->top > 0);ps->top--;
}
int Stacksize(Stack* ps)
{assert(ps);return ps->top;
}
Datatype TopData(Stack* ps)
{assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1];
}
bool IsEmpty(Stack* ps)
{assert(ps);return (ps->top == 0);
}
bool isValid(char* s) {Stack st;InItStack(&st);char top;while (*s){if (*s == '(' || *s == '[' || *s == '{'){StackPush(&st, *s);}else{if(IsEmpty(&st)){DestoryStack(&st);return false;}top=TopData(&st);StackPop(&st);if((*s==']'&&top!='[')||(*s==')'&&top!='(')||(*s=='}'&&top!='{')){DestoryStack(&st);return false;}}s++;}bool ret = IsEmpty(&st);DestoryStack(&st);return ret;
}

?????????棧相對于鏈表和順序表沒有那么多的操作,更為簡單,但在實際應用時數據結構更加復雜,但是別擔心,后續學習C++后可以直接使用現成的庫函數,不需要再對棧的各個操作進行實現。


??

總結

????????棧是一種重要的數據結構,它以后進先出的方式操作數據。棧在遞歸算法、表達式求值、函數調用等場景中發揮著重要作用。通過學習棧,我們能夠更好地理解數據結構的本質和算法的設計思想。棧不僅僅是一種數據存儲的方式,更是一種思維方式和問題解決的工具。無論是計算機科學的學習者、程序設計的愛好者,還是正在準備面試的求職者,通過探索棧的原理和應用,我們能夠提升自己的編程能力和解決問題的能力。讓我們一起深入探索棧的魅力,為編程之路增添新的色彩。最后,感謝閱讀!

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

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

相關文章

CVE漏洞復現-CVE-2021-22555 Linux Netfilter 權限提升漏洞

CVE-2021-22555 Linux Netfilter 權限提升漏洞 漏洞描述 近日,互聯網公開了Linux Netfilter權限提升漏洞的POC及EXP,相關CVE編號:CVE-2021-22555。該漏洞在kCTF中被用于攻擊kubernetes pod容器實現虛擬化逃逸,該漏洞已在Linux內…

用chatGPT從左右眼圖片生成點云數據

左右眼圖片 需求 需要將左右眼圖像利用視差生成三維點云數據 先問問chatGPT相關知識 進一步問有沒有現成的軟件 chatGPT提到了OpenCV,我們讓chatGPT用OpenCV寫一個程序來做這個事情 當然,代碼里面會有一些錯誤,chatGPT寫的代碼并不會做模…

Arduino驅動MQ2模擬煙霧傳感器(氣體傳感器篇)

目錄 1、傳感器特性 2、硬件原理圖 3、控制器和傳感器連線圖 4、驅動程序 MQ2氣體傳感器,可以很靈敏的檢測到空氣中的煙霧、液化氣、丁烷、丙烷、甲烷、酒精、氫氣等氣體,與Arduino結合使用,可以制作火災煙霧報警、液化氣、丁烷、丙烷、甲烷、酒精、氫氣氣體泄露報警等相…

面試題. 字符串壓縮

字符串壓縮。利用字符重復出現的次數,編寫一種方法,實現基本的字符串壓縮功能。比如,字符串aabcccccaaa會變為a2b1c5a3。若“壓縮”后的字符串沒有變短,則返回原先的字符串。你可以假設字符串中只包含大小寫英文字母(a…

【JavaEE進階】Spring 更簡單的讀取和存儲對象

文章目錄 一. 存儲Bean對象1. 配置掃描路徑2. 添加注解存儲 Bean 對象2.1 使用五大類注解存儲Bean2.2 為什么要有五大類注解?2.3 有關獲取Bean參數的命名規則 3. 使用方法注解儲存 Bean 對象3.1 方法注解儲存對象的用法3.2 Bean的重命名3.3 同?類型多個 Bean 報錯 …

Spring Boot單元測試與Mybatis單表增刪改查

目錄 1. Spring Boot單元測試 1.1 什么是單元測試? 1.2 單元測試有哪些好處? 1.3 Spring Boot 單元測試使用 單元測試的實現步驟 1. 生成單元測試類 2. 添加單元測試代碼 簡單的斷言說明 2. Mybatis 單表增刪改查 2.1 單表查詢 2.2 參數占位符 ${} 和 #{} ${} 和 …

學點Selenium玩點新鮮~,讓分布式測試有更多玩法

前 言 我們都知道 Selenium 是一款在 Web 應用測試領域使用的自動化測試工具,而 Selenium Grid 是 Selenium 中的一大組件,通過它能夠實現分布式測試,能夠幫助團隊簡單快速在不同的環境中測試他們的 Web 應用。 分布式執行測試其實并不是一…

opencv,opengl,osg,vulkan,webgL,opencL,cuda

OpenCV OpenCV是一個基于BSD許可(開源)發行的跨平臺計算機視覺和機器學習軟件庫,可以運行在Linux、Windows、Android和Mac OS操作系統上。 它輕量級而且高效——由一系列 C 函數和少量 C 類構成,同時提供了Python、Ruby、MATLAB等…

安卓java A應用切換到B應用,來回切換不執行OnCreate

需求:安卓java如何做到A應用切換到B應用,如果B應用沒啟動就啟動,如果B應用已經啟動就僅僅切換到B應用。B應用再切換回A應用,不要重復執行OnCreate! 在 A 應用中的: 在 A 應用中,如果你希望在切換回 B 應用…

小米平板6Max14即將發布:自研G1 電池管理芯片,支持33W反向快充

明天晚上7點(8 月 14 日),雷軍將進行年度演講,重點探討“成長”主題。與此同時,小米將推出一系列全新產品,其中包括備受矚目的小米MIX Fold 3折疊屏手機和小米平板6 Max 14。近期,小米官方一直在…

分布式搜索ElasticSearch-ES(一)

一、ElasticSearch介紹 ES是一款非常強大的開源搜索引擎,可以幫我們從海量的數據中快速找到我們需要的內容。 ElasticSearch結合kibana、Logstash、Beats,也就是elastic stack(ELK),被廣泛運用在日志數據分析,實時監控等領域。 …

accumulate函數的簡單應用

accumulate函數是C numeric庫中的一個函數&#xff0c;主要用來對指定范圍內元素求和&#xff0c;但也自行指定一些其他操作&#xff0c;如范圍內所有元素相乘、相除等。 使用前需要引用頭文件&#xff1a; #include <numeric>函數共有四個參數&#xff0c;其中前三個為…

Ajax 筆記(二)—— Ajax 案例

筆記目錄 2. Ajax 綜合案例2.1 案例一-圖書管理2.1.1 渲染列表2.1.2 新增圖書2.1.3 刪除圖書2.1.4 編輯圖書 2.2 案例二-背景圖的上傳和更換2.2.1 上傳2.2.2 更換 2.3 案例三-個人信息設置2.3.1 信息渲染2.3.2 頭像修改2.2.3 信息修改2.3.4 提示框 Ajax 筆記&#xff1a; Ajax…

React Native 列表組件基礎知識

ScrollView 組件 ScrollView組件是一個容器滾動組件&#xff0c;當容器超出指定寬高時就可以進行滾動交互。 ScrollView組件是一次性渲染所有的 React 子組件&#xff0c;這在性能上是比較差的&#xff0c;所以不建議當列表特別長的時候使用此組件。 接下來列舉幾個常用的一…

HTML(JavaEE初級系列12)

目錄 前言&#xff1a; 1.HTML結構 1.1認識HTML標簽 1.2HTML文件基本結構 1.3標簽層次結構 1.4快速生成代碼框架 2.HTML常見標簽 2.1注釋標簽 2.2標題標簽&#xff1a;h1-h6 2.3段落標簽&#xff1a;p 2.4換行標簽&#xff1a; br 2.5格式化標簽 2.6圖片標簽&#…

【數據結構?堆】經典問題:k路歸并

題目描述 k路歸并問題&#xff1a;   把k個有序表合并成一個有序表。&#xff08; k < 10^4 &#xff09; 輸入輸出格式 輸入格式&#xff1a; 輸入數據共有 2*k1 行。   第一行&#xff0c;一個整數k&#xff08; k < 10^4 &#xff09;&#xff0c;表示有k個有序…

【詳細教程】學會使用Python隧道代理

作為一名專業爬蟲程序猿&#xff0c;我深知在進行網絡數據采集時&#xff0c;可能會面臨網絡封鎖、隱私泄露等問題。今天&#xff0c;我將與大家分享如何學會使用Python隧道代理&#xff0c;幫助我們自由訪問受限網站&#xff0c;同時保護了解探索Python隧道代理&#xff01; …

3.1 Spring MVC概述

1. MVC概念 MVC是一種編程思想&#xff0c;它將應用分為模型&#xff08;Model&#xff09;、視圖&#xff08;View&#xff09;、控制器&#xff08;Controller&#xff09;三個層次&#xff0c;這三部分以最低的耦合進行協同工作&#xff0c;從而提高應用的可擴展性及可維護…

C++ opencv:視頻讀取、變換顏色風格、保存

1. 相關知識點 VideoCapture&#xff1b; applyColorMap&#xff1b; VideoWriter&#xff1b; 2. 代碼 編寫代碼main.cpp: #include<iostream> #include "opencv2/opencv.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/highgu…

解開謎團:為什么紅黑樹勝過AVL樹?

為什么紅黑樹勝過AVL樹 博主簡介一、引言1.1、紅黑樹和AVL樹簡介1.2、紅黑樹在某些方面優于AVL樹 二、紅黑樹和AVL樹的基本原理2.1、紅黑樹的定義和性質2.2、AVL樹的定義和性質2.3、對比兩種樹結構的特點 三、插入和刪除操作的復雜性比較3.1、紅黑樹的插入操作和平衡性維護3.2、…