数据结构——栈的学习

一、什么是栈?

  1. 栈是限制在一端进行操作(插入、删除)的线性表;
  2. 我们俗称为堆栈;
  3. 只不过是一种特殊的线性表,有顺序栈、也有链式栈

二、栈的特点

  1. 具有先进后出的特点,即先进栈的数据后出栈(LIFO);
  2. 入栈出栈可交替进行;
对于特点1、2经常出面试题目:
一个栈的入栈序列为ABCDE,则不可能的出栈序列为? (AB)
A:ECDBA
B:DCEAB
C:DECBA
D:ABCDE
E:EDCBA	
解析:A:E先出可以做到,C绝对不能在E先出的情况下比B先出栈;所以A错;
      B:D最先出栈,说明之前进栈顺序为ABCD,出栈时B先出A后出,故B错
      C:C先出栈,所以是A,B,C,D依次入栈,D出栈E入栈,E出栈,CBA依次出栈;
      D,E:正确;
3.栈的操作只能在线性表的表尾进行,即是我们所说的栈顶;
4.对于栈的实现一般才用顺序结构;

三、栈的实现

typedef int ElemType;


typedef struct
{
    ElemType *base;//指向栈底的指针
    ElemType *top;//指向栈顶的指针
    int StackSize;//栈的当前大小
}sqstack_t;
/*创建一个栈*/
void stack_cread(sqstack_t *q)
{




    q->base = (ElemType *)malloc(sizeof(ElemType)*MAX_SIZE);//用malloc函数申请一个(sizeof(ElemType)*MAX_SIZE大小的空间,并用base指向它;


    if(!q->base)
    {
        printf("creat stack failed\n");//为空,申请失败;
        exit(0);
    }
    q->top=q->base;//创建时栈为空,即我们的栈顶指针和栈底指针指向同一个地方;
    q->StackSize=MAX_SIZE;//我们申请的栈的大小为100


}
//入栈操作
void stack_push(sqstack_t *q,ElemType e)
{
    if(q->top-q->base>=q->StackSize)
    {
        q->top=(ElemType *)realloc(q->top,sizeof(ElemType)*(MAX_SIZE+ADD_SIZE));//当栈满时,我们给它增加空间;
        if(!q->top)
        {
            printf("creat failed\n");
            exit(0);
        }
        q->StackSize+=ADD_SIZE;
    }
    *(q->top)=e;
    q->top++;//当前的栈顶指针指向的空间为空,就是这个存储单元没值,入栈时直接放了该空间,然后指针++,方便下次的入栈操作
}
void stack_pop(sqstack_t *q,ElemType *e)
{
    if(q->top==q->base)
    {
        printf("stack is empty\n");
        exit(0);
    }
    else
        *e=*(--(q->top));//因为当前的栈顶指针指向的空间为空,就是这个存储单元没值,方便入栈,所以出栈要先--;


}

四、栈的应用

1、实现逆波兰标识法:利用栈的特点;输入为数字,就入栈,输入为运算符号出栈两次,根据符号计算结果,然后结果入栈;

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>

typedef char ElemType;
//typedef int ElemType;
#define MAX_SIZE 100
#define ADD_SIZE 10

typedef struct
{
    ElemType *base;//指向栈底的指针
    ElemType *top;//指向栈顶的指针
    int StackSize;//栈的当前大小
}sqstack_t;

void stack_cread(sqstack_t *);
void stack_push(sqstack_t *q,ElemType e);
ElemType stack_pop(sqstack_t *q);
int stack_clear(sqstack_t *q);
void stack_show(sqstack_t *q);


int main()
{
    char ch;
    int i=0;
    char  arr[10];
    double num1,num2,num;


    sqstack_t Q;
    stack_cread(&Q);

    printf("please input the number:");
    scanf("%c",&ch);
    while(ch!='#')
    {
        while(isdigit(ch)||ch=='.')//判断是否为数字
        {
                arr[i++]=ch;
                arr[i]='\0';
                scanf("%c",&ch);
                if(ch==' ')
                {
                    num=atoi(arr);//字符串转为数值
                    stack_push(&Q,num);
                    i=0;
                }
        }
        scanf("%c",&ch);
        switch (ch)
        {
            case '+':num1=stack_pop(&Q);
                     num2=stack_pop(&Q);
                     stack_push(&Q,num1+num2);
                     break;
            case '-':num1=stack_pop(&Q);
                     num2=stack_pop(&Q);
                     stack_push(&Q,num2-num1);
                     break;
            case '*':num1=stack_pop(&Q);
                     num2=stack_pop(&Q);
                     stack_push(&Q,num1*num2);
                     break;
            case '/':num1=stack_pop(&Q);
                     num2=stack_pop(&Q);
                     if(num1!=0)
                        stack_push(&Q,num2/num1);
                     else
                        printf("error");
                     break;
        }


    }
     printf("%f",(float)stack_pop(&Q));
return 0;
 }








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值