什麼是棧?
- 個人認爲棧的靈魂在於:先入後出(FILO)
1、定義棧:
#define MAXSIZE 100
typedef int datatype;
typedef struct{
datatype a[MAXSIZE];
int top;
}sequence_stack;
2、相關函數:
// 棧(順序存儲)初始化
//文件名seqsinit.c, 函數名init_sequence_stack()
void init_sequence_stack(sequence_stack *st)
{
st->top=0;
}
// 判斷棧(順序存儲)是否爲空
// 文件名seqsempt.c, 函數名is_empty_sequence_stack()
// 返回值類型:int類型。1表示空,0表示非空
int is_empty_stack(sequence_stack st)
{
return( st.top? 0 : 1 );
}
//取得棧頂(順序存儲)結點值
//文件名seqsfirs.c, 函數名get_top()
datatype get_top(sequence_stack st)
{
if ( is_empty_stack(st) )
{printf("\n棧是空的!"); exit(1);}
else
return st.a[st.top-1];
}
// 棧(順序存儲)的插入操作
//文件名seqspush.c, 函數名push()
void push(sequence_stack *st,datatype x)
{
if(st->top==MAXSIZE)
{ printf("\nThe sequence stack is full!");
exit(1); }
st->a[st->top]=x;
st->top++;
}
// 棧(順序存儲)的刪除操作
// 文件名seqspop.c, 函數名pop()
void pop(sequence_stack *st)
{
if(st->top==0)
{printf("\nThe sequence stack is empty!"); exit(1);}
st->top--;
}
我們可以怎麼利用這種數據結構?
-
既然棧是這種先入後出的結構,那麼我們可以利用這種結構進行 比較!!!!
-
我們可以把我們想比較的數據放入棧中,然後將待比較的數據
不斷的送入棧中比較完後,若達到某種條件就送入棧中;同時我們可以靈活的運用棧頂對棧內數據進行刪改。
棧依據存儲結構可分爲:順序棧、鏈式棧。對於C語言,使用順序棧時,可用數據存儲數據!!!
經典案例1:
- 給定一個只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判斷字符串是否有效。
- 有效字符串需滿足:
- 左括號必須用相同類型的右括號閉合。
- 左括號必須以正確的順序閉合。
- 注意空字符串可被認爲是有效字符串。
利用棧,我們可以解答:
- 當自左向右掃描一個表達式時,凡是遇到的開括號(或稱左括號)都期待有一個和它對應的閉括號(或稱右括號)與之匹配。
- 按照括號正確匹配的規則,在自左向右掃描一個表達式時,後遇到的開括號比先遇到的開括號更加期待有一個閉括號與之匹配。
- 依據此可有以下代碼:
/* 判斷表達式括號是否匹配 */
/* 文件名seqmatch.c,函數名match_huohao() */
/*******************************************/
int match_kuohao( char c[ ] )
{
int i=0;
sequence_stack s;
init_sequence_stack(&s);
while ( c[i] != '#' )
{
switch( c[i] )
{
case '{': push(&s, c[i]); break;
case '[': push(&s, c[i]); break;
case '(': push(&s, c[i]); break;
case '}': if( !is_empty_sequence_stack(s) && get_top(s)=='{' )
{pop(&s);break;} else return 0;
case ']': if(!is_empty_sequence_stack(s) && get_top(s)=='[' )
{pop(&s);break;} else return 0;
case ')': if(!is_empty_sequence_stack(s) && get_top(s)=='(' )
{pop(&s);break;} else return 0;
}
i++;
}
return (is_empty_sequence_stack(s));/*棧空則匹配,否則不匹配*/
}
LeetCode代碼:
https://leetcode-cn.com/problems/valid-parentheses/
bool isValid(char * s){
int len = 0, i = 0, j = 0;
char *S_array = NULL;
len = strlen(s);
S_array = (char*)malloc( len*sizeof(char) );
for(i=0; i < len; i++)
{
switch(*(s+i))
{
case '(':S_array[j] = '(';
break;
case '[':S_array[j] = '[';
break;
case '{':S_array[j] = '{';
break;
case ')':if( j!=0 && (S_array[j-1] == '(') ) j -= 2;
else return false;
break;
case ']':if( j!=0 && (S_array[j-1] == '[') ) j -= 2;
else return false;
break;
case '}':if( j!=0 && (S_array[j-1] == '{') ) j -= 2;
else return false;
break;
}
j++;
}
if(j == 0) return true;
else return false;
}