栈()

一、基本概念

栈是只允许在一段进行插入和删除的线性表

                                                

假如有一组数{1,2,3,4},存入栈里,1先到达栈底,然后依次进入,此时从栈底到栈顶分别为1,2,3,4

当要把栈中的数取出去,由于我们只能在栈顶操作,所以先取出4,依次为3,2,1

可以明显看到,有着先进后出的特点。

栈顶:线性表允许进行插入和删除的一端。

栈底:固定的,不允许插入和删除的另一端。

空栈:不含任何元素的空表。

            先来分析一波。即然是个栈,它可能是空的,也可能非空。

           我们往进存东西,先要看看它,是否为空,若空着,直接存,否则我们就不能存。

            当我们要取东西的是否,先看看这个栈空不空,若为空,啥也没有就不能取出东西,有的话就取。

基本操作:

  1. InitStack(&S):初始化一个空栈
  2. StackEmpty(S),判断一个栈是否为空,若栈空则返回true,否则返回false
  3. Push(&S,x):进栈,若栈S未满,则将x加入使之成为新栈顶
  4. Pop&S,x):出栈,若栈S非空,则用x返回栈顶元素
  5. ClearStack(&S):销毁栈,并释放栈S占用的存储空间,

              此外还有个重要的公式,当n个元素以某种顺序进栈,并在任意时刻出栈(满足先进后出的前提),

            所获得的元素排列数目N恰好满足Catalan()函数的计算,

                           N=\frac{1}{n+1}C_{2n}^{n}         

                即然栈它是操作受限的线性表,按存储结构分为:顺序栈和链式

二、顺序栈⭐⭐⭐⭐

采用顺序存储的栈称为顺序栈,它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针(top)指示当前栈顶的位置

1.顺序栈的实现

#define MaxSize 100   //定义栈中元素的最大个数

typedef struct{

                Elemtype data[MaxSize];

                int top;

}SqStack;

2.基本状态和操作

(1)栈空状态

       S.top==-1

为啥栈空不是用0表示呢?在有些书上是s.top===0,因为这样会浪费一个元素大小的空间。所以不少书都用-1

数组下标从0开始,栈空应当s.top<0,因此栈空时栈顶指针s.top==-1

(2)栈满状态

           S.top==maxSize-1

maxSize是栈中最大元素个数,则maxSize-1 为栈满时栈顶元素在数组中的位置,因为数组下标从0开始。这里规定指针top为-1时栈空,即top==0的数组位置也可以存有数据元素

(3)进栈操作

元素x进栈,S.data[++S.top]=x分解为两步就是 ++(S.top)  和S.data[S.top]=x

即然规定top为-1时栈空,则元素进栈猜哦在必须是先移动指针,再进入元素,因为数组下标不存在-1

(4)出栈操作

x=S.data[S.top--]分解为两步就是 x=S.data[S.top] 和 --(S.top) 

进栈次序决定了出栈操作次序,因为进栈操作时先变动栈顶指针,再存入元素,

因此出栈操作必须为先取出元素,再变动指针。

如果反过来,会丢失栈顶元素

基本运算实现

(1)初始化

     void initStack(SqStack &st)

           {  s.top==-1;}           ///初始化栈顶指针

(2)判栈空

         bool StackEmpty(Stack S){

                if(S.top==-1)       return true;

                 else return false;     

}

(3)进栈

          bool Push(SqStack &S,Elemtype x){

               if(S.top==MaxSize-1)          //栈满报错

                        return false;

              S.data[++S.top]=x;       //指针先加1,再入栈

                           return true;

}

(4)出栈

bool Pop(SqStack &S,Elemtype x){

               if(S.top==-1)             //栈空,报错

                        return false;

                     x=S.data[S.top--];   //先出栈,再减1   

                           return true;

}

(5)读栈顶元素

                bool GetTop(SqStack S,Elemtype &x){

                        if(S.top==-1)        return false;       //栈空报错

                        x=S.data[S.top];          //记录栈顶元素

                          return true;

}

3.共享栈

利用栈底位置相对不变的特性,可让两个顺序栈共享一个一维数据空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸。

           连个栈的栈顶指针都指向栈顶元素,top0=-1时,0号占位空,top1=MaxSize-1时1号栈为空;

        仅当两个栈顶指针相邻(top1-top0=1)时,判断为栈满。当0号栈进栈时,top0先加1,在赋值,1号栈进栈时top1先减去1在赋值;出栈时刚刚相反。

              共享栈时为了有效利用存储空间,两个栈的空间相互调节,只在整个存储空间被占满菜发生上溢。

三、链栈

采用链式存储的栈称为链栈,它的优点时便于多个栈共享存储空间和提高效率,且不存在栈满上溢。通常采用单链表实现,并规定所有操作都是在表头进行

typedef struct LinkStack{

           Elemtype data;     //数据域

           struct LinkStack *next;     //指针域

} *LStack;  //栈类型定义

下面的了解即可

//初始化
void initQueue(LiQueue *&lqu){
     lqu=(LiQueue*)malloc(sizeof(LiQueue));
     lqu->front=lqu->rear=NULL;
}
判空
int isQuenueEmpty(LiQueue *lqu){
   if(lqu->rear==NULL || lqu->front==NULL)
           return 1;
   else
        return 0;
}
void enQueue(LiQueue * lqu,int x){  //入队
    QNode *p;
    p=(QNode*)malloc(sizeof(QNode));
    p->data=x;
    p->next=NULL;
    if(lqu->rear==NULL)
        lqu->front=lqu->rear=p;
    else
    {
        lqu->rear->next=p;
        lqu->reaer=p;
    }
}
//来自https://bbs.csdn.net/topics/392467555
//大佬代码收藏下

#include<stdio.h>
 
#define Size 50
 
typedef char stackelemtype;
 
typedef struct
{
    stackelemtype elem[Size];
    int top;
}seqstack;
 
void Initstack(seqstack *s)
{
    s->top = -1;
}
int push(seqstack *s,stackelemtype x)
{
    if(s->top == Size-1)
        return 0;
    s->top++;
    s->elem[s->top] = x;
    return 1;
}
int pop(seqstack *s,stackelemtype *x)
{
    if(s->top == -1)
        return 0;
 
    //else
    //{
    *x = s->elem[s->top];
    s->top--;
    return 1;
    //}
}
int gettop(seqstack *s,stackelemtype *x)
{
    if(s->top==-1)
        return 0;
 
    printf("弹出栈顶元素\n");
    *x = s->elem[s->top];
    printf("%c\n", *x);
    return 1;
}
 
void OutStack(seqstack*s)
{  //输出这个栈
    if(s->top==-1) {
        printf("这是一个空栈");
        return;
    }
 
    //else{
    while(s->top > -1)
    {
        printf("%c ", s->elem[s->top]);
        s->top--;
    }
    //}
}
int main()
{
 
    seqstack p;
    int i,k;
    //char b[Size], x=NULL;
    char b[Size], x = 0;
 
    Initstack(&p);//初使化顺序栈
 
    printf("加入元素个数\n");
    scanf("%d",&k);
    printf("输入栈的元素\n");
    for(i=0;i<k+1;i++)
        scanf("%c", &b[i]);
    for(i=0;i<k+1;i++)
        push(&p,b[i]);
    gettop(&p, &x);
    printf("top elem = %c\n", x);
    pop(&p,&x);
    printf("剩余栈的元素\n");
    OutStack(&p);
    printf("\n");
 
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值