【數據結構】棧 與【LeetCode】20.有效的括號詳解

目錄

  • 一、棧
    • 1、棧的概念及結構
    • 2、棧的實現
    • 3、初始化棧和銷毀棧
    • 4、打印棧的數據
    • 5、入棧操作---棧頂
    • 6、出棧---棧頂
      • 6.1棧是否為空
      • 6.2出棧---棧頂
    • 7、取棧頂元素
    • 8、獲取棧中有效的元素個數
  • 二、棧的相關練習
    • 1、練習
    • 2、AC代碼

個人主頁,點這里~
數據結構專欄,點這里~

在這里插入圖片描述

一、棧

1、棧的概念及結構

:?種特殊的線性表,其只允許在固定的?端進行元素的插入和刪除元素操作。進行數據插入和刪除操作的?端稱為棧頂,另?端稱為棧底。棧中的數據元素遵守后進先出LIFO(Last In First Out)的原則。
壓棧:棧的插入操作叫做進棧/壓棧/入棧入數據在棧頂
出棧:棧的刪除操作叫做出棧出數據也在棧頂
在這里插入圖片描述
以上這張圖片很好的反映了棧的結構,及出入棧的順序。

2、棧的實現

棧的實現?般可以使用數組或者鏈表實現,相對而言數組的結構實現更優?些。因為數組在尾上插入,數據的代價比較小。數組在尾上插入整型數據只需要增加4個字節,但鏈表增加的字節就大的多了

typedef int STDataType;
typedef struct Stack
{STDataType* arr;int top;     //指向棧頂位置int capacity;//數據容量
}ST;

3、初始化棧和銷毀棧

我們已經知道用什么方法實現棧,并且已經將棧的結構寫出來了,接下來就該初始化了。
初始化:

void StackInit(ST* ps)
{ps->arr = NULL;ps->top = 0;ps->capacity = 0;
}

初始化棧十分簡單,只需把arr數組置為空,棧頂top和容量capacity置為0即可。

銷毀:

void StackDestroy(ST* ps)
{if (ps->arr)//如果不為NULL{ps->arr = NULL;}ps->top = ps->capacity = 0;
}

以上就是棧的初始化以及銷毀的代碼了,和我們講順序表的時候差不多。

4、打印棧的數據

void SPrint(ST* ps)
{assert(ps);for (int i = 0;i < ps->top;i++){printf("%d", ps->arr[i]);if (i < ps->top - 1){printf("->");}}
}

5、入棧操作—棧頂

我們知道棧只能從棧頂入數據和出數據,所以我們就大概知道如何入棧了。

//入棧---棧頂
void StackPush(ST* ps, STDataType x)
{assert(ps);if (ps->top == ps->capacity)//如果棧空間滿了就增容{int newcapacity = ps->capacity == 0 ? 4 : 2 * ps -> capacity;STDataType* set = (STDataType*)realloc(ps->arr,sizeof(STDataType) * newcapacity);if (set == NULL){perror("realloc fail!");return 1;}ps->arr = set;ps->capacity = newcapacity;}ps->arr[ps->top++] = x;
}

以上是入棧的代碼,但在入棧之前呢,我們要考慮棧空間是不是滿了,也就是棧頂是不是和容量一樣大,如果滿了,我們需要增容,在進行增容之前,我們還要考慮topcapacity是不是都為0,如果為0的話,我們要把容量大小置為4,否則的話容量擴大為二倍。

測試代碼:

#include "Stack.h"void test()
{ST plist;StackInit(&plist);StackPush(&plist, 1);StackPush(&plist, 2);StackPush(&plist, 3);SPrint(&plist);
}int main()
{test();return 0;
}

測試結果
在這里插入圖片描述

6、出棧—棧頂

在實現出棧之前我們要考慮棧里面的元素是否為空,如果為空就終止操作,所以我們先寫一個判空函數,這樣我們就可以在出棧之前知道棧是否為空了。

6.1棧是否為空

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

這里用到了bool類型記得要加上#include<stdbool.h>頭文件。

6.2出棧—棧頂

void StackPop(ST* ps)
{assert(!StackEmpty(ps));ps->top--;
}

這里實現出棧是只需要實現top減一即可,因為我們不會訪問top之后的元素。

7、取棧頂元素

STDataType StackTop(ST* ps)
{assert(!StackEmpty(ps));return ps->arr[ps->top - 1];
}

這里取棧頂元素時,我們只需要判斷一下棧是否為空,再將棧頂元素返回即可。

8、獲取棧中有效的元素個數

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

以上就是棧的常見操作,接下來讓我們做一道練習題試一下吧!

二、棧的相關練習

1、練習

題目描述:
在這里插入圖片描述
題目鏈接,點擊這里~

沒有做過的,可以先看題目思考一下,下面會給出題解。

我們根據題目描述可以知道題目讓我們判斷括號匹配是否正確,如果正確返回true,如果錯誤返回false
我們在利用棧思想(先進后出)進行求解的時候,可以當遇到左括號讓它入棧,然后再遇到右括號的時候讓棧頂的和它匹配(在括號匹配的情況下,最后出現的左括號總與最先出現的右括號匹配),如果不匹配就一定是非法的,返回false,如果都匹配的話就是合法的,返回true這里可以用數組模擬棧。我們在遇到左括號例如'('時我們可以在棧中保存')',這樣在比較的時候容易比較。

  • 特殊情況一:
    字符數目是奇數,只要是奇數就一定不匹配,直接返回false
    int len=strlen(s);if(len%2==1){return false;}
  • 特殊情況二:
    如果全是左括號,那么最后棧頂top一定大于0,而如果是正確匹配的情況下,到最后top肯定是0。因為我們初始化top0。所以遇到top大于0的情況直接返回false
    //到最后top大于0的情況if(top>0){return false;}
  • 如果全是右括號,那么在比較的時候,top一定為0,此時棧中沒有元素,也就無法比較,所以遇到比較時top0的情況也直接返回false
            if(top==0||s[i]!=stack[--top]){return false;}

2、AC代碼

AC代碼:

bool isValid(char* s) 
{int len=strlen(s);if(len%2==1){return false;}char stack[10005];int top=0;int i;for(i=0;i<len;i++){if(s[i]=='('){stack[top++]=')';}else if(s[i]=='['){stack[top++]=']';}else if(s[i]=='{'){stack[top++]='}';}else{if(top==0||s[i]!=stack[--top]){return false;}}}if(top>0){return false;}return true;
}

總結:
以上就是本期博客分享的全部內容啦!如果覺得文章還不錯的話可以三連支持一下,你的支持就是我前進最大的動力!
技術的探索永無止境! 道阻且長,行則將至!后續我會給大家帶來更多優質博客內容,歡迎關注我的CSDN賬號,我們一同成長!
(~ ̄▽ ̄)~

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

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

相關文章

攻破tensorflow,勇創最佳agent(2)---損失(loss) 準確率(accuracy)問題

實戰播: 怎么判定一個模型好不好,你設置的值對不對? 需要再看幾個值: 例如: model Sequential()for units in model_structure:model.add(Dense(units, activationrelu))model.add(Dropout(train_config.get(dropout_rate, 0.3)))model.add(Dense(1, activationsigmoid)) 他…

pdfh5 pdf

踩坑1&#xff1a; 渲染失敗 &#xff08;1&#xff09;在vue項目中&#xff0c;讀取本地的pdf文件需要放到public下static文件夾中&#xff0c;不能放在別的地方&#xff1b; &#xff08;2&#xff09;引用時&#xff0c;不能使用相對路徑&#xff0c;因為使用public文件下…

6.5 模擬專題:LeetCode 38. 外觀數列

1. 題目鏈接 LeetCode 38. 外觀數列 2. 題目描述 給定一個正整數 n&#xff0c;生成外觀數列的第 n 項。外觀數列的定義如下&#xff1a; 第 1 項為 "1"。第 n 項是對第 n-1 項的描述。例如&#xff0c;第 2 項描述第 1 項&#xff08;"1"&#xff09;為…

什么是具身智能

具身智能&#xff08;Embodied Intelligence&#xff09;是人工智能與機器人學交叉的前沿領域&#xff0c;強調智能體通過身體與環境的動態交互實現自主學習和進化&#xff0c;其核心在于將感知、行動與認知深度融合?。通俗地講&#xff0c;就是機器人或者智能系統在物理環境中…

git命令使用小記(打補丁)

需求&#xff1a;需要從開發分支提取本人提交代碼&#xff0c;然后合并到主分支 一、制作補丁包 mkdir -p patches for commit in $(git log commitA..commitB --author"username" --reverse --prettyformat:"%h"); do …

mapbox基礎,加載popup彈出窗

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言1.1 ??mapboxgl.Map 地圖對象1.2 ??mapboxgl.Map style屬性1.3 ??popup 彈出窗 api1.3.1 ??構造函數1.…

C++11--(1)

目錄 1.列表初始化 {}初始化 C98中 C11中 內置置類型和自定義類型 創建對象也適用 std::initializer_list 2.變量類型推導 auto C98 C11 decltype nullptr 3.范圍for循環 4.STL中一些變化 array 1.創建和初始化 2.訪問元素 ?編輯 3.修改操作 4.支持迭代器…

Promise的狀態和方法是什么?

Promise 的狀態和方法 1. Promise 的狀態 一個 Promise 可以處于以下三種狀態之一&#xff1a; - Pending&#xff08;待定&#xff09;&#xff1a;初始狀態&#xff0c;表示異步操作正在進行中&#xff0c;Promise 還沒有被解決或拒絕。 - Fulfilled&#xff08;已完成&…

Windows云服務器支持哪些數據庫管理系統?

Windows云服務器因其良好的兼容性和企業級支持&#xff0c;廣泛用于網站托管、企業管理系統、金融應用、數據分析等場景。在這些應用中&#xff0c;數據庫管理系統(DBMS)起著至關重要的作用。Windows 服務器支持多種數據庫&#xff0c;包括關系型數據庫(SQL)和非關系型數據庫(N…

MongoDB 實際工作中應用場景

博主介紹&#xff1a;?全網粉絲5W&#xff0c;全棧開發工程師&#xff0c;從事多年軟件開發&#xff0c;在大廠呆過。持有軟件中級、六級等證書。可提供微服務項目搭建與畢業項目實戰&#xff0c;博主也曾寫過優秀論文&#xff0c;查重率極低&#xff0c;在這方面有豐富的經驗…

03 相機標定圖像采集

學完本文,您將獲取一下技能: 1:如何提升標定質量,如選擇標定板,標定圖像采集的注意事項, 2:實現標定圖像自動篩選的代碼 3:量產場景如何通過一張圖像來標定相機 為了實現良好的標定效果,以下因素在標定數據采集前必須設置得當。 標定板選擇 標定板尺寸準確材料平…

GitHub美化個人主頁3D圖表顯示配置操作

這個功能主要是用的這個開源倉庫&#xff1a;https://github.com/yoshi389111/github-profile-3d-contrib 想看效果的話&#xff0c;我的個人主頁&#xff1a;https://github.com/Sjj1024 開始操作 1.創建自己的github主頁屬性項目——跟你github用戶名一致即可&#xff0c;…

buu-jarvisoj_fm-好久不見52

格式化字符串漏洞題 x等于4x等于4???????x等于4???????x等于4 可以知道是第11個參數&#xff0c;%11$ 定位到這個位置&#xff0c;然后%n往這個位置寫入4 1.先用pwndbg調試得到偏移量 2.查看獲取x的地址 3.構造ROP鏈&#xff0c;發送連接 from pwn import *# …

AwesomeQt分享3(含源碼)

AwesomeQt 這個項目包含了多個Qt組件的使用示例&#xff0c;旨在展示Qt各種強大功能的實現方式。 源碼分享 github: awesome_Qtgitee: 后續同步 項目進度 QCustomPlot曲線控件示例 支持排序和篩選的列表控件示例 支持排序和篩選的表格控件示例 屬性表示例 Dock窗口示例 自繪…

ubuntu 安裝 g++

文章目錄 前提一、安裝 g1.1 安裝1.2 驗證 前提 安裝 tflite_support 報錯 error: subprocess-exited-with-error RuntimeError: Unsupported compiler -- at least C11 support is needed!一、安裝 g 1.1 安裝 # 安裝編譯工具鏈&#xff08;如g&#xff09;和依賴庫 sudo …

【NLP 50、損失函數 KL散度】

目錄 一、定義與公式 1.核心定義 2.數學公式 3.KL散度與交叉熵的關系 二、使用場景 1.生成模型與變分推斷 2.知識蒸餾 3.模型評估與優化 4.信息論與編碼優化 三、原理與特性 1.信息論視角 ?2.優化目標 3.?局限性 四、代碼示例 代碼運行流程 核心代碼解析 抵達夢想靠的不是狂熱…

使用QT畫帶有透明效果的圖

分辨率&#xff1a;24X24 最大圓 代碼: #include <QApplication> #include <QImage> #include <QPainter>int main(int argc, char *argv[]) {QImage image(QSize(24,24),QImage::Format_ARGB32);image.fill(QColor(0,0,0,0));QPainter paint(&image);…

【Unity網絡編程知識】使用Socket實現簡單TCP通訊

1、Socket的常用屬性和方法 創建Socket TCP流套接字 Socket socketTcp new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 1.1 常用屬性 1&#xff09;套接字的連接狀態 socketTcp.Connected 2&#xff09;獲取套接字的類型 socketTcp.So…

青少年編程與數學 02-013 初中數學知識點 02課題、概要

青少年編程與數學 02-013 初中數學知識點 02課題、概要 一、數與代數二、圖形與幾何三、統計與概率四、綜合與實踐五、課程理念與目標 根據2022年版義務教育數學課程標準&#xff0c;初中數學知識點可以總結為以下四大領域。 一、數與代數 數與式 有理數與實數&#xff1a;理解…

深入探索 libarchive

深入探索 libarchive&#xff1a;跨平臺歸檔處理的終極解決方案 一、背景與歷史沿革 1.1 歸檔處理的演進之路 從1979年tar格式的誕生到現代云存儲時代&#xff0c;歸檔技術經歷了四個關鍵階段&#xff1a; Unix時代&#xff1a;tar/cpio主導系統備份互聯網黎明期&#xff1…