顺序栈详解

一、顺序栈定义

顺序栈(也称为数组栈)是一种基于数组实现的栈数据结构。栈是一种“后进先出”(Last In First Out, LIFO)的数据结构,最后一个进入的元素最先被取出。顺序栈就是使用一个数组来存储元素的栈,它遵循栈的特性。

在顺序栈中,我们将数组的第一个索引(位置0)作为栈顶,最后添加(push)的元素将放在数组的最后一个索引位置,而弹出(pop)操作则从数组的第一个索引位置开始。

二、顺序栈的6种基本操作

  • 初始化操作
  • 判断栈是否为空
  • 判断栈是否为满
  • 进栈操作
  • 出栈操作
  • 取栈顶元素

三、顺序栈的实现

1.顺序栈的定义

typedef struct
{
    DataType *data; /* 堆空间 */
    int maxsize;
    int top;        /* 栈顶指针 */
}SeqStack;

2.初始化

int init(SeqStack *S, int MaxSize)
{
    /*申请内存空间*/
    S->data = (DataType*)malloc(sizeof(DataType)*MaxSize);

    if(!S->data)
    {
        printf("内存申请错误,初始化失败![10001]\n");
        return 10001;
    }
    S->maxsize = MaxSize;
    S->top = -1;
    return 0;
}

3.进栈

int push(SeqStack *S, DataType x)
{
    /*是否满?*/
    if(full(S))
    {
        printf("栈已满!10002\n");
        return 10002;
    }

    S->top++;            /*移动指针*/
    S->data[S->top] = x;/*放入数据*/
    return 0; /*OK*/
}

4.出栈

int pop(SeqStack *S, DataType *x)
{
    /*是否空?*/
    if(empty(S))
    {
        printf("栈为空!10003\n");
        return 10003;
    }

    *x = S->data[S->top];    /*栈顶元素赋值给x*/
    S->top--;                /*移动栈顶指针*/    

    return 0;
}

5.取栈顶元素

int get_top(SeqStack *S, DataType *x)
{
    /*是否空?*/
    if(empty(S))
    {
        printf("栈为空!10003\n");
        return 10003;
    }

    *x = S->data[S->top];    /*栈顶元素赋值给x*/

    return 0;
}

6.栈是否为空


int empty(SeqStack *S)
{
    return (S->top == -1)?1:0;
}

7.栈是否满

int full(SeqStack *S)
{
    return (S->top == S->maxsize - 1)?1:0;
}

8.销毁

int destroy(SeqStack *S)
{
    free(S->data);
    return 0;
}

9.栈的应用

 (1).十进制转换为二进制

int d_to_b(int d)
{
    SeqStack S;
    int b;

    /*初始化栈*/
    init(&S,32);

    /*d不为0,余数进栈*/
    while(d)
    {
        push(&S, d % 2);
        d /= 2;
    }
    
    /*依次出栈*/
    while(!empty(&S))
    {
        pop(&S,&b);
        printf("%d", b);
    }

    /*销毁栈*/
    destroy(&S);
}

 (2).后缀表达式计算

int expression()
{
    SeqStack S;
    int i;
    int op1, op2;    
    int x;

    char exp[20]; /*后缀表达式*/

    init(&S, 10);

    printf("请输入一个后缀表达式(eg. 56+):");
    scanf("%s", exp);

    for(i=0;i<strlen(exp);i++)
    {
        switch(exp[i])
        {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            /*入栈*/
            push(&S, exp[i]-48);
            break;
        case '+':
            /*出2个*/
            pop(&S, &op1);
            pop(&S, &op2);
            x = op1 + op2;
            push(&S, x);
            break;
            
        case'-':
            pop(&S,&op1);
            pop(&S,&op2);
            x=op1-op2;
            push(&S,x);
            break;

        case '*':
            pop(&S, &op1);
            pop(&S, &op2);
            x = op1 * op2;
            push(&S, x);
            break;
            
        case '/':
            pop(&S,&op1);
            pop(&S,&op2);
            x=op1/op2;
            push(&S,x);
    
        }
    }
    pop(&S, &x);
    printf("计算结果为:%s = %d\n", exp, x);
    destroy(&S);
}

四、完整代码

main.c

#include <stdio.h>
#include <string.h>
#include "seqstack.h"

/*十进制转换为二进制*/
int d_to_b(int d);

/*后缀表达式计算*/
int expression();

int main(int argc, char* argv[])
{
    SeqStack S;
    int cmd;
    int d;
    DataType x;
    int maxsize;
    char yn;

    do
    {
        printf("---------顺序栈演示程序-----------\n");
        printf(" 1. 初始化\n");
        printf(" 2. 入栈\n");
        printf(" 3. 出栈\n");
        printf(" 4. 取栈顶元素\n");
        printf(" 5. 栈是否空?\n");
        printf(" 6. 栈是否满?\n");
        printf(" 7. 销毁栈\n");
        printf(" 8. 栈的应用\n");

        printf(" 9. 寻求帮助\n");
        printf("请选择(0~9,0退出):");
        scanf("%d", &cmd);
        switch(cmd)
        {
        case 1:
            printf("请输入栈的最大存储空间(MaxSize):");
            scanf("%d", &maxsize);
            if(!init(&S, maxsize))
            {
                printf("栈已初始化!\n");
            }
            break;
        case 2:
            printf("请输入入栈元素:x=");
            scanf("%d", &x);
            if(!push(&S, x))
            {
                printf("元素【%d】已入栈!\n", x);

            }
            break;
        case 3:
            printf("确定要出栈(出栈后数据不可恢复,y|n,n)?");
            getchar();
            scanf("%c", &yn);
            if(yn == 'y' || yn == 'Y')
            {
                if(!pop(&S, &x))
                {
                    printf("栈顶元素【%d】已出栈!\n", x);
                }
            }
            break;
        case 4:
            if(!get_top(&S, &x)){
                printf("栈顶元素【%d】\n", x);
            }
            break;    
        case 5:
             if(empty(&S)){
                  printf("栈为空!\n"); 
              }else{
                  printf("栈不为空!\n");
              }
             break;    
        case 6:
             if(full(&S)){
                 printf("栈已满!\n"); 
             }else{
                 printf("栈未满!\n"); 
             } 
              break;
        case 7:
                destroy(&S); 
                  printf("栈已销毁!\n"); 
              
              break;    

        case 8:
            do
            {
                printf("----------8.栈的应用------------\n");
                printf(" 1. 十进制转换为二进制\n");
                printf(" 2. 后缀表达式计算\n");            
                printf(" 0. 返回\n");
                printf("请选择:");
                scanf("%d", &cmd);

                if(cmd == 1)
                {
                    printf("请输入一个十进制数:");
                    scanf("%d", &d);
                    printf("二进制为:");
                    d_to_b(d);
                    printf("\n");
                }

                if(cmd == 2)
                {
                    expression();
                }
            }while(cmd!=0);
            cmd = -1;
            break;
        case 9:
            printf("本程序为顺序栈的演示程序,由陈嘉俊设计开发,程序完成了关于顺序栈的相关功能!\n");
            break;
        }

    }while(cmd!=0);
    return 0;
}

/*十进制转换为二进制*/
int d_to_b(int d)
{
    SeqStack S;
    int b;

    /*初始化栈*/
    init(&S,32);

    /*d不为0,余数进栈*/
    while(d)
    {
        push(&S, d % 2);
        d /= 2;
    }
    
    /*依次出栈*/
    while(!empty(&S))
    {
        pop(&S,&b);
        printf("%d", b);
    }
    
    /*销毁栈*/
    destroy(&S);
}

/*后缀表达式计算*/
int expression()
{
    SeqStack S;
    int i;
    int op1, op2;    
    int x;
    char exp[20]; /*后缀表达式*/
    init(&S, 10);
    printf("请输入一个后缀表达式(eg. 56+):");
    scanf("%s", exp);

    for(i=0;i<strlen(exp);i++)
    {
        switch(exp[i])
        {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            /*入栈*/
            push(&S, exp[i]-48);
            break;
        case '+':
            /*出2个*/
            pop(&S, &op1);
            pop(&S, &op2);
            x = op1 + op2;
            push(&S, x);
            break;
            
        case'-':
            pop(&S,&op1);
            pop(&S,&op2);
            x=op1-op2;
            push(&S,x);
            break;

        case '*':
            pop(&S, &op1);
            pop(&S, &op2);
            x = op1 * op2;
            push(&S, x);
            break;
            
        case '/':
            pop(&S,&op1);
            pop(&S,&op2);
            x=op1/op2;
            push(&S,x);
        }
    }
    pop(&S, &x);
    printf("计算结果为:%s = %d\n", exp, x);
    destroy(&S);
}

seqstack.c

/*
    seqstack.c
*/
#include <stdio.h>
#include <malloc.h>
#include "seqstack.h"


/* 1. 初始化 */
int init(SeqStack *S, int MaxSize)
{
    /*申请内存空间*/
    S->data = (DataType*)malloc(sizeof(DataType)*MaxSize);

    if(!S->data)
    {
        printf("内存申请错误,初始化失败![10001]\n");
        return 10001;
    }
    S->maxsize = MaxSize;
    S->top = -1;
    return 0;
}


/* 2. 进(入)栈 */
int push(SeqStack *S, DataType x)
{
    /*是否满?*/
    if(full(S))
    {
        printf("栈已满!10002\n");
        return 10002;
    }

    S->top++;            /*移动指针*/
    S->data[S->top] = x;/*放入数据*/
    return 0; /*OK*/
}

/* 3. 出栈 */
int pop(SeqStack *S, DataType *x)
{
    /*是否空?*/
    if(empty(S))
    {
        printf("栈为空!10003\n");
        return 10003;
    }

    *x = S->data[S->top];    /*栈顶元素赋值给x*/
    S->top--;                /*移动栈顶指针*/    

    return 0;
}

/* 4. 取栈顶元素 */
int get_top(SeqStack *S, DataType *x)
{
    /*是否空?*/
    if(empty(S))
    {
        printf("栈为空!10003\n");
        return 10003;
    }

    *x = S->data[S->top];    /*栈顶元素赋值给x*/

    return 0;
}

/* 5. 栈为空?*/
int empty(SeqStack *S)
{
    return (S->top == -1)?1:0;
}

/* 6. 栈满?*/
int full(SeqStack *S)
{
    return (S->top == S->maxsize - 1)?1:0;
}


/* 7. 销毁*/
int destroy(SeqStack *S)
{
    free(S->data);
    return 0;
}

seqstack.h

/*
    seqstack.h
    顺序栈
*/
 
typedef int DataType;
 
 
typedef struct
{
    DataType *data; /* 堆空间 */
    int maxsize;
    int top;        /* 栈顶指针 */
}SeqStack;
 
 
/* 1. 初始化 */
int init(SeqStack *S, int MaxSize);
 
/* 2. 进(入)栈 */
int push(SeqStack *S, DataType x);
 
/* 3. 出栈 */
int pop(SeqStack *S, DataType *x);
 
/* 4. 取栈顶元素 */
int get_top(SeqStack *S, DataType *x);
 
/* 5. 栈为空?*/
int empty(SeqStack *S);
 
/* 6. 栈满?*/
int full(SeqStack *S);
 
/* 7. 销毁*/
int destroy(SeqStack *S);
 

五、运行结果

六、小结

本文简单介绍了顺序栈的定义,基本操作,并且提供了顺序栈实现的相关代码以及运行结果,仅供参考,如有不妥,敬请指导。

七、参考文献

1.李刚 刘万辉 “数据结构(C语言版”

2.代课老师的代码

3.AI

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值