栈的定义:栈(stack)是限定仅在表位进行插入和删除操作的线性表。
允许插入和删除的一端被称为栈顶,另一端称为栈底,不含任何数据元素的栈称为空栈。栈又称为后进先出的线性表,简称为LIFO结构。

栈的抽象数据类型
在这里插入图片描述
注意:栈本身是一个线性表,所以线性表的顺序和链式存储他都适用。

一.顺序结构

用一个top变量来指示栈顶元素在数组中的位置,判定为栈空的条件是top==-1。

1.栈的结构定义

    typedef int SElemType;//根据实际情况,不一定是int
    typedef struct
    {
        SElemType data[MAXSIZE];
        int top;
    }SqStack;

进栈和出栈不在这里写了。

2.两栈共享空间
顺序存储结构有缺陷,那就是他必须在最开始就确定数组存储空间的大小,不够用只能靠编程手段来扩充容量。但对于两个相同类型的栈,我们可以最大限度的利用他们的空间来进行操作。

我们的做法是将一个栈的栈底作为数组的始端(下标为0处),另一个栈为数组的末端(下标为n-1处)我们假设这两个栈分别为栈1和栈2,top1和top2为他们的栈顶指针,只要这两个指针不见面,这两个栈就可以一直使用,如下所示
在这里插入图片描述
虽然这个图上看上去像两个不同的栈合并到了一起,要有两个数组。其实不然,这是在一个数组上进行操作的。
!!!这里有一点特别强调,判断栈1为空的条件只有top1==-1,判断栈2为空的条件只有top2 == n
判断他们栈满的条件是 top1 + 1 == top2
这个栈满中的栈指的是这个栈结构,不是单一的栈1或者栈2,栈1或者栈2满的条件是只要他们过了中间那处,他们就满了,当然top1==n-1是栈1也是满的,同理栈2也是。
两栈共享空间的结构如下:

typedef int Status
typedef struct
{
    SElemType data[MAXSIZE];
    int top1;
    int top2;
}sqDoubleStack;

两栈共享空间的push方法,除了要插入的元素值参数外,还需要一个判断是栈1还是栈2的栈号参数stackNumber
push代码如下

Status Push(SqDoubleStack *S,SElemType e,int stackNumber)
{
    if(S->top1+1==S->top2)//栈满,不能加新元素
        return ERROR;
    if(stackNumber==1)//栈1有元素进栈
        S->data[++S->top1]=e;
    else if(stackNumber==2)
        S->data[--S->top2]=e;
    return OK;
}

Pop代码如下

Status Pop(SqDoubleStack *S,SElemType e,int stackNumber)
{
    if(stackNumber==1)
    {
        if(S->top1==-1)    //说明栈1已经是空栈了
            return ERROR; 
        *e=S->data[S->top1--];  //将栈1顶部元素出栈
    }
    else if(stackNumber==2)
    {
        if(S->top1==MAXSIZE)    //说明栈1已经是空栈了
            return ERROR; 
        *e=S->data[S->top2++];  //将栈1顶部元素出栈
    }
    return OK;
}

一般而言,使用这种数据结构,通常是当两个栈的空间需求有相反关系时,一方增一方减。除非情况特殊,一般不要使用,容易写混。

二.链式结构

栈的链式存储结构简称为链栈。
对于链栈来说是不需要头结点的,定义一个top指针,指向链栈的栈顶。对于空栈来说,链表原定义是头指针指向空,那么来链栈的空其实就是top==NULL的时候。
链栈的结构如下
在这里插入图片描述
ps.这里补充一下,这是我当时看到代码遇到的问题,是关于typedef后加指针的问题
这里的LinkStackPtr由他所定义的东西,相当于定义了一个指向struct stackNode结构的指针。
LinkStackPtr a等价于 struct stackNode *a

链式结构的进栈出栈操作如下图所示
进栈
在这里插入图片描述
在这里插入图片描述
出栈
在这里插入图片描述
最后总结一下,当元素个数不确定时最好用链栈,否则用顺序栈会好一些。

本片文章参考自《大话数据结构》程杰 清华大学出版社

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值