限定性线性表—栈

栈(堆栈)和队列是两种重要的抽象数据类型,是一类操作受限制的特殊线性表,其特殊性在于限制插入和删除等运算的位置。
在栈中,用户只能在指定的一端插入和删除元素,因此具有后进先出或先进后出的特性;在队列中,用户只能在一端插入元素,而在另一端删除元素,因此呈现先进先出或后进后出的特性。
从数据结构角度看,它们都是线性结构。

栈作为一种限定性线性表,是将线性表的插入和删除运算限制为仅在表的一端进行,通常将表中允许进行插入、删除操作的一端称为栈顶(Top),因此栈顶的当前位置是动态变化的,它由一个称为栈顶指针的位置指示器指示。同时,表的另一端被称为栈底(Bottom)。当栈中没有元素时称为空栈。ebp栈底、esp栈顶。
栈的插入操作被形象地称为进栈(栈顶插入)或入栈,删除操作称为出栈(删除栈顶)或退栈。
每次进栈的元素都被放在原栈顶元素之上而成为新的栈顶,而每次出栈的总是当前栈中“最新”的元素,即最后进栈的元素。栈又称为后进先出的线性表,简称LIFO表。

栈作为一种特殊的线性表,在计算机中主要有两种基本的存储结构:顺序存储结构和链式存储结构。我们称顺序存储的栈为顺序栈,链式存储的栈为链栈。

栈之顺序栈

顺序栈是用顺序存储结构实现的栈,即利用一组地址连续的存储单元一次存放自栈底到栈顶的数据元素,同时由于栈操作的特殊性,还必须附设一个位置指针top(栈顶指针)来动态地指示栈顶元素在顺序栈中的位置。通常以top=-1表示空栈。

顺序栈定义如下

typedef int DataType;
#define MAXSIZE (10)
typedef struct SeqStack
{
     DataType array[MAXSIZE];
     int top;//用来存放栈顶元素的下标值,top为-1表示空栈
             //or 表示当前个数
} SeqStack;

相关代码
顺序栈

栈的应用非常广泛,经常会出现在一个程序中需要同时使用多个栈的情况。若使用顺序栈,会因为对栈空间大小难以准确估计而产生有的栈溢出、有的栈空间还很空闲的情况。为了解决这个问题,可以让多个栈共享一个足够大的数组空间,通过利用栈的动态特性来使其存储空间互相补充,这就是多栈的共享技术。

双端栈
在顺序栈的共享技术中最常用的是两个栈的共享技术,即双端栈:它主要利用了“栈底位置不变,而栈顶位置动态变化”的特性。首先申请一个共享的一维数组空间S[M],将两个栈的栈底分别放在一维数组的两端,分别是0,M-1。由于两个栈顶动态变化,这样可以形成互补,使得每个栈可用的最大空间与实际使用的需求有关。
由此可见,两栈共享要比两个栈分别申请M/2的空间利用率更高。

双端栈定义如下

typedef int DataType;
#define M (10)
typedef struct DqStack
{
     DataType array[M];
     int top[2];//top[0]和top[1]分别为两个栈顶指示器,top[0]=-1和top[1]=M表示空栈
} DqStack;

栈之链栈

链栈即采用链表作为存储结构实现的栈。
为便于操作,这里采用带头结点的单链表实现栈。
由于栈的插入和删除操作仅限制在表头位置进行,所以链表的表头指针就作为栈顶指针。top为栈顶指针(也就是头结点的位置信息)。若top->next=NULL,则代表栈空。

链栈定义如下

typedef int DataType;
typedef struct StackNode
{
     DataType data;
     struct StackNode *next;
} StackNode;

多栈(两个以上的栈)
在顺序栈中已经介绍了两个栈共享一个地址连续的空间(数组S),用空间S的两个端0和M-1分别作为两个栈的栈底,从而使得两个栈的总空间固定不变。在实际问题中需要同时使用两个以上栈的话,采用顺序栈来处理极为不方便。采用多个单链表来实现多个链栈是很好的实现途径。

多栈定义如下

typedef int DataType;
#define M (10)//M个链栈
typedef struct StackNode
{
     DataType data;
     struct StackNode *next;
} StackNode;
StackNode *top[M];
//top[0],top[1],…,top[M-1]分别是M个链栈的栈顶指针,分别指向M个不同的链栈。

实际中用链栈会更多一点,因为扩容方便。
但是我们平时自己写的话用顺序表会更多一点,因为顺序表的尾插和尾删都很方便,我们只要把尾部作为顶部就可以了。

栈的应用举例

1、括号匹配
相关代码
括号匹配
2、逆波兰表达式(后缀表达式)
正常的表达式->逆波兰表达式
a+b -> a,b,+
a+(b-c) -> a,b,c,-,+
a+(b-c)×d -> a,b,c,-,d,×,+
a+d×(b-c) -> a,d,b,c,-,×,+
a = 1+3 -> a = 1,3,+

相关代码
逆波兰表达式

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值