STL之栈 【帆帆帆笔记系列】

来源:互联网 发布:诺基亚手机下载软件 编辑:程序博客网 时间:2024/06/05 18:30

 栈:

  栈(stack)又名堆栈,它是一种运算受限线性表。其特点在于仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一 个栈插入新元素又称作进栈(入栈 or 压栈);从一个栈删除元素又称作出栈(退栈)。

       其重要的特性可以简述为LIFO(Last In First Out),也就是“后入先出”,类似于在桶中放盘子,只能从顶部放上去,也只能从最高处拿出去。

       如下图,我们可以用一种序列来表示这个栈[a1,a2...an-1,an>,其中尖括号>表示栈顶,中括号[表示栈底。

                                                                      


使用标准库的栈和队列时,先包含相关的头文件

#include<stack>

定义栈如下:

stack<int> stk;

栈提供了如下的操作

empty()   如果栈为空返回true 否则返回false 

size()      返回栈中元素的个数

pop()       删除栈顶元素但不返回其值

top()        返回栈顶的元素,但不删除该元素

push()     在栈顶压入新元素

栈是一端受限,一段允许进行操作的线性表。我自己理解时,会将它理解成一个装书的盒子。放书,取书,就是进行的操作。这个的特点就是,你放了一踏书,现在你想取书,你只能先把上面的书一个个取出来,即:先放的后取,后放的先取。放在栈上说,就是先进后出。

明白了栈的定义,现在要实际的实际,首先是它的逻辑结构:线性表。它是线性的。

现在是它的存储结构:最常采用的是顺序存储和链式存储(见好多书或资料都说的最常采用的是顺序存储和链式存储,百度了下不常见的没有找到)。其中顺序存储用数组,链式存储用链表。

1.顺序存储:

  先进行分析下:首先要分配一个足够大的数组,现在有了这个数组,需要的还有,必须有个东西能一个控制一端不让操作(数组的前端从下标为0开始),一端要进行增删,这样就可以说是具备了栈有的特点,不让操作的叫栈底,进行操作的是栈顶。


                                                      

  在顺序栈中,有上溢和下溢的概念,当压入数据大于存储范围就会发生上溢出,当栈中无数据时进行取出操作就会发生下溢出,下溢本身可以表示栈为空栈,因此可以用它来作为控制转移的条件。

2.链式存储:

  控制入栈出栈的端口,栈顶一般是链表的头,第一个节点,栈底一般是最后一个节点。(可以避免顺序存储的溢出),同时节省空间,要多少,申请多少。链表的运用中同时要注意一旦申请了,最后要记得释放,不然会带来不可预计的后果。

                                                           

  若是栈中元素的数目变化范围较大或不清楚栈元素的数目,就应该考虑使用链式存储结构



 栈的具体应用:

   编号为1,2,3,4 的四列火车通过一个栈式的列车调度站,可能得到的调度结果有哪些?如果
有n 列火车通过调度站,请设计一个算法,输出所有可能的调度结果。 
解题思路:栈具有先进后出、后进先出的特点,因此,任何一个调度结果应该是1 ,2 ,3 ,4
全排列中的一个元素。由于进栈的顺序是由小到大的,所以出栈序列应该满足以下条件:对于
序列中的任何一个数其后面所有比它小的数应该是倒序的,例如4321 是一个有效的出栈序列,
1423不是一个有效的出栈结果(4 后面比它小的两个数 2 ,3 不是倒序)。据此,本题可以通过
算法产生n 个数的全排列,然后将满足出栈规则的序列输出。
依此递归定义,递归算法如下:

#include<bits/stdc++.h>using namespace std;int cont=1;void out(int str[],int n);void perm(int str[],int k,int n){    int i,temp;    if(k==n-1)        out(str,n);    else    {        for(i=k;i<n;i++)        {            temp=str[k];            str[k]=str[i];            str[i]=temp;            perm(str,k+1,n);            temp=str[i];            str[i]=str[k];            str[k]=temp;        }    }}void out(int str[],int n)//判断是否满足栈进出规则{    int l,m,flag=1,b[2];    for(int i=0;i<n;i++)    {        m=0;        for(int j=i+1;j<n&&flag;j++)        {            if(str[i]>str[j])            {                if(m==0)                {                    b[m++]=str[j];                }                else                {                    if(str[j]>b[0])                        flag=0;                    else b[0]=str[j];                }            }        }    }    if(flag)    {        printf(" %2d:",cont++);        for(int i=0;i<n;i++)        {            printf("%d",str[i]);        }        printf("\n");    }}int main(){    int str[100],n,i;    scanf("%d",&n);    for(i=0;i<n;i++)    {        str[i]=i+1;    }    perm(str,0,n);    printf("\n");    return 0;}




原创粉丝点击