【LeetCode之栈和队列】:关于栈和队列经典的OJ题(用C语言实现,附图详解)
LeetCode題目
- 1、括號(hào)匹配問題
- 2、用隊(duì)列實(shí)現(xiàn)棧
- 3、用棧實(shí)現(xiàn)隊(duì)列
- 4、設(shè)計(jì)循環(huán)隊(duì)列
1、括號(hào)匹配問題
LeetCode鏈接: 【20. 有效的括號(hào)】
這道題就是經(jīng)典的利用棧解決問題的例子;思路如下:
遍歷一遍字符串,如果遇倒左括號(hào)就入棧,如果遇倒右括號(hào)取棧頂?shù)脑剡M(jìn)行匹配并出棧頂?shù)脑?#xff0c;如果相匹配就繼續(xù),不匹配就返回false。
但是要注意這樣只能檢驗(yàn)出左右括號(hào)個(gè)數(shù)相等的情況下才可以,如果左右括號(hào)個(gè)數(shù)不相等呢?
- 如果左括號(hào)多于右括號(hào),并且遍歷結(jié)束后它們都是匹配的,這種情況并不是完全匹配的,因?yàn)闂@镞€有元素剩余;所以遍歷字符串后要加一個(gè)判斷棧是否為空,只要棧為空了才是全部匹配完,沒有剩余。 比如:“[[[[[((()))”
- 如果右括號(hào)多余左括號(hào),有可能導(dǎo)致棧是空的,棧里面沒有元素可以取了,這種情況也是不匹配的;所以取棧頂元素的前面要加一個(gè)判斷棧是否為空,如果棧為空說明右括號(hào)多余左括號(hào),是不匹配的。比如:”((([[[ ]]]]]]]]]"
代碼實(shí)現(xiàn)如下:
//C語言中沒有棧,我們先實(shí)現(xiàn)一個(gè)棧 //構(gòu)建棧如下: typedef char STDataType; struct Stack {STDataType* a;int top;int capacity; }; typedef struct Stack ST;//初始化棧 void StackInit(ST* ps); //銷毀棧 void StackDestroy(ST* ps); //入棧 void StackPush(ST* ps, STDataType x); //出棧 void StackPop(ST* ps); //獲取棧的元素個(gè)數(shù) int StackSize(ST* ps); //獲取棧頂?shù)脑?/span> STDataType StackTop(ST* ps); //判斷棧是否為空 bool StackEmpty(ST* ps);void StackInit(ST* ps) {ps->a = NULL;ps->capacity = 0;ps->top = 0; }void StackDestroy(ST* ps) {free(ps->a);ps->a = NULL;ps->capacity = ps->top = 0; }void StackPush(ST* ps,STDataType x) {assert(ps);if (ps->capacity == ps->top){ps->capacity = ps->capacity > 0 ? ps->capacity * 2 : 2;STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * sizeof(STDataType));if (tmp == NULL){return;}else{ps->a = tmp;}}ps->a[ps->top] = x;ps->top++; }void StackPop(ST* ps) {assert(ps);assert(ps->top > 0);ps->top--; }int StackSize(ST* ps) {assert(ps);assert(ps->top > 0);return ps->top; }STDataType StackTop(ST* ps) {assert(ps);assert(ps->top > 0);return ps->a[ps->top - 1]; }bool StackEmpty(ST* ps) {assert(ps);return ps->top == 0; }bool isValid(char * s){ST st;StackInit(&st);while(*s!='\0'){switch(*s){//壓棧case '(':case '[':case '{':StackPush(&st,*s);s++;break;//取棧頂?shù)臄?shù)據(jù)進(jìn)行匹配case ')':case ']':case '}'://出棧,從棧里面取做括號(hào),棧里面的元素不能為空,//防止右括號(hào)過多,導(dǎo)致取到棧里面沒有元素可以取,這也是不匹配if(StackEmpty(&st)){StackDestroy(&st);return false;}//取棧頂?shù)臄?shù)據(jù)和字符比較char top=StackTop(&st);StackPop(&st);if(top=='(' && *s==')' || top=='[' && *s==']' ||top=='{' && *s=='}'){s++;}else{StackDestroy(&st);return false;}}}//最后要判斷棧是否為空//棧是空的說明才完全匹配,如果還要剩余說明沒有是左括號(hào)多了,不匹配if(StackEmpty(&st)){StackDestroy(&st);return true;}else{StackDestroy(&st);return false;}}2、用隊(duì)列實(shí)現(xiàn)棧
LeetCode鏈接: 【225. 用隊(duì)列實(shí)現(xiàn)棧】
思路: 這是要我們利用隊(duì)列的性質(zhì)去實(shí)現(xiàn)棧,隊(duì)列的性質(zhì)是先入先出,而棧的性質(zhì)是后入先出;
所以我們利用兩個(gè)隊(duì)列來實(shí)現(xiàn)棧,一個(gè)為空隊(duì)列,一個(gè)不為空隊(duì)列;入棧:就往不為空的隊(duì)列里面入,而 出棧就是: 只保留不為空的隊(duì)列的最后一個(gè)元素,前面的元素都插入空隊(duì)列中;然后再把最后一個(gè)元素出掉就是出棧了。
代碼實(shí)現(xiàn)如下:
3、用棧實(shí)現(xiàn)隊(duì)列
LeetCode鏈接: 【232. 用棧實(shí)現(xiàn)隊(duì)列】
思路分析如下:
代碼實(shí)現(xiàn)如下:
4、設(shè)計(jì)循環(huán)隊(duì)列
LeetCode鏈接: 【622. 設(shè)計(jì)循環(huán)隊(duì)列】
做這道題之前,我們先來了解什么是循環(huán)隊(duì)列?它的解釋如下:
循環(huán)隊(duì)列是把順序隊(duì)列首尾相連,把存儲(chǔ)隊(duì)列元素的表從邏輯上看成一個(gè)環(huán),成為循環(huán)隊(duì)列。
循環(huán)隊(duì)列就是將隊(duì)列存儲(chǔ)空間的最后一個(gè)位置繞到第一個(gè)位置,形成邏輯上的環(huán)狀空間,供隊(duì)列循環(huán)使用。在循環(huán)隊(duì)列結(jié)構(gòu)中,當(dāng)存儲(chǔ)空間的最后一個(gè)位置已被使用而再要進(jìn)入隊(duì)運(yùn)算時(shí),只需要存儲(chǔ)空間的第一個(gè)位置空閑,便可將元素加入到第一個(gè)位置,即將存儲(chǔ)空間的第一個(gè)位置作為隊(duì)尾。
循環(huán)隊(duì)列可以更簡(jiǎn)單防止偽溢出的發(fā)生,但隊(duì)列大小是固定的。
所以循環(huán)隊(duì)列的結(jié)構(gòu)搞清楚了,寫起來就比較簡(jiǎn)單了,循環(huán)隊(duì)列有兩種實(shí)現(xiàn)方式,可以使用數(shù)組實(shí)現(xiàn),也可以使用循環(huán)鏈表實(shí)現(xiàn)。下面分別來介紹。
鏈表實(shí)現(xiàn)如下:
數(shù)組方式實(shí)現(xiàn)如下:
代碼實(shí)現(xiàn)如下:
總結(jié)
以上是生活随笔為你收集整理的【LeetCode之栈和队列】:关于栈和队列经典的OJ题(用C语言实现,附图详解)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: es java 查询为空和非空的数据
- 下一篇: 认识1M带宽、1Mbps、1Mb/s 区