栈是什么
“栈”(读音“zhan”)是计算机科学里最重要且最基础的数据结构之一,英文名:stack;它与堆(HEAP), 队列(QUEUE) 都是学习计算机的人都必须知道的数据结构!如果你问一个人,他居然不知道“栈”是什么?那么你大概可以判断:他没有学过计算机,或者即使学过,也只是学习了皮毛而已。
栈的一个很重要的特点
先进后出: FILO(First In Last Out)的原则存储数据。你可以参考如下的动图,其实,你可以把“栈”想象成一个“薯片的圆筒”——你可以把薯片一个一个的放进去,最先放的那个薯片一定是放到圆筒的最底层;当你想吃的时候,你从上面开始一个一个拿着吃,那么你最先拿出来的一定是“最后放进去”的!这就是“先进后出”。我想有生活经验的人一定能理解!
现在用专业的语言来解释:栈按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。你参考如下的图片:
如何实现“栈”
"栈"这种思想——先进后出(或者后进先出),我们可以用很多东西实现栈这种思想:比如说用普通的数组解决、用动态数组解决、或用STL(标准模板库)里的stack直接解决!都可以!
栈的最朴素的一个实现方法
通过一个用“栈”的思想解决的问题,我们来说明下,比如:表达式括号匹配问题。这个问题是:
假设一个表达式由英文字母(小写)、运算符(十,一,,/)和左有小(圆)括号构成,以“@”作为表达式
的结束符。请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配则返回“YES”;否则返回“NO”。
表达式长度小于255,左圆括号少于 20 个。
输入:
输入文件 stack.in 包括一行数据,即表达式。
输出:
输出文件 stack.out 包括一行,即“YES”或“NO”
样例输入:
样例1:
2(x十y)/(1-x)@
样例 2:
(25十x)*(ax(a+b+b)@
样例输出:
样例 1:
YES
样例 2:
NO
要解决这个问题,我们首先要抽丝剥茧——理解“栈”的精髓——就是几个操作而已:入栈、出栈、查看栈顶元素等。大家看到上图中有个指向栈顶的指针,我给它命名为t。这个很重要!上题要解决的是“左右圆括号是否匹配”的问题。那么我可以这么想:最开始的时候,我假设t=0, 然后我一个一个读入字符串里的每个元素,如果遇到了左括号,就让t++(自增1),如果遇到了右括号,就让t--(自减1)。那么,如果表达式里的左右括号是成对匹配的,必然最后t=0了! 这一点看看自己能够想明白不?如果扫描完整个表达式,最终t不等于0,那么肯定有不匹配的括号!所以我们就用这种想法就能写出简单的代码解决上面的问题:
//左右括号匹配:
#include
using namespace std;
char a[10001];
int i=0;
int tot=0;
int main(){
scanf("%s",&a); //输入表达式;(2+3)*(47-5)@
// cin>>a; //第二种方式;
// cin.getline(a,256);
while(a[i]!='@'){
//如果遇到左括号就“入栈”
if(a[i]=='(') tot++; //模拟入栈动作
if(a[i]==')') {
//过滤那些“先写右括号”的
if(tot>0) tot--;
else{
tot--;
break;
}
}
i++;
}
if(tot!=0) cout<<"NO";
else cout<<"YES";
}
这是一种“最意象”的模拟栈的实现。(未完待续)