栈的特点是先进后出。但要说明的是这种特性只是在正常情况正常操作下才成立,那什么是正常什么是不正常呢?
所谓的正常操作:严格按照顺序把所有数据压入栈中之后再依次压出栈即为正常常规操作。例如我们的带一组数据:1,2,3,4,5;把他们押入栈后出栈的顺序自然为5,4,3,2,1。
那什么情况会出现4,5,3,2,1的出栈顺序?大部分第一次接触此类情况可能会想有问题吧,题出错之类的,这时你就要思考,是不是严格的输入栈操作?或者说是不是依次按顺序出栈入栈?问题就解决了!
解析:我们按照正常顺序先把1,2,3,4压入栈,然后关键步骤来了,这时把4压出栈,4就是第一个出栈的;然后把5入栈,最后按照顺序依次出栈,那么我们得到的最终出栈顺序为4,5,3,2,1。
做个练习:
一个栈的入栈序列是a,b,c,d,e则栈的不可能的输出序列是:()
A edcba B decba C dceab D abcde
我把答案解析放在最后。
来看下面一道题
数据结构实验之栈与队列七:出栈序列判定
Description
给一个初始的入栈序列,其次序即为元素的入栈次序,栈顶元素可以随时出栈,每个元素只能入栈依次。输入一个入栈序列,后面依次输入多个序列,请判断这些序列是否为所给入栈序列合法的出栈序列。
例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个出栈序列,但4,3,5,1,2就不可能是该序列的出栈序列。假设压入栈的所有数字均不相等。
Input
第一行输入整数n(1<=n<=10000),表示序列的长度。
第二行输入n个整数,表示栈的压入顺序。
第三行输入整数t(1<=t<=10)。
后面依次输入t行,每行n个整数,表示要判断的每一个出栈序列。
Output
每个测试案例输出一行,如果由初始入栈序列可以得到该出栈序列,则输出yes,否则输出no。
Sample
Input
5
1 2 3 4 5
2
4 5 3 2 1
4 3 5 1 2
Output
yes
no
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,i,m,a[10001],b[10001];
cin>>n;
for(i=0; i<n; i++)
cin>>a[i];
cin>>m;
while(m--)
{
stack<int> st;
for(i=0; i<n; i++)
cin>>b[i];
int key_a=0,key_b=0;
while(key_b<n)
{
if(st.empty())
st.push(a[key_a++]);
else
{
if(st.top()!=b[key_b])
{
if(key_a<n)
st.push(a[key_a++]);
else
break;
}
else
{
st.pop();
key_b++;
}
}
}
if(st.empty())
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}
C
逐个分析答案,A选项就是我们前面所说的正常顺序出入栈的结果;B选项我们也分析过了就是文章开头的例子;D选项的结果是压入一个弹出一个;C选项,我们先分析ab之后的顺序,出栈为dce我们可以理解为压入d后弹出d,在弹出c,之后再压入e弹出e,没问题可以保障cde的入栈顺序,那么b在a之后入栈,就不可能比a后出栈所以错误。