详解栈与顺序栈

目录

1.栈的定义

2.顺序栈

3.顺序栈的实现

 4.完整的Demo

5.小结 

6.参考文献


 

1.栈的定义

栈(stack)又被称为堆栈,它是一种只允许在一端(一般是表尾)进行插入和删除操作的线性表。

允许进行操作的一端称为“栈顶”;
另一端称为“栈底”;
当栈中没有元素时称为“空栈”;
栈是一个特殊的线性表;
特点:后进先出(LIFO);

2.顺序栈

顺序栈是栈的顺序实现。顺序栈是指利用顺序存储结构实现的栈。采用月地址连续的存储空间(数组)依次存储栈中数据元素,由于入栈和出栈运算都是在栈顶进行,而栈底位置是固定不变的,可以将栈底位置设置在数组空间的起始处;栈顶位置是随入栈和出栈操作而变化的,故需用一个整型变量top来记录当前栈顶元素在数组中的位置。

运算概述:初始化,入栈,出栈,获取栈顶元素和判断栈是否为空或为满与销毁

3.顺序栈的实现

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;
}

 执行结果:

 8.栈的应用——十进制转化为二进制

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);
}

9.栈的应用——后缀表达式的计算

void expression() {
    SeqStack S;
    int i,op1, op2,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 = op2 + op1;
                push(&S, x);
                break;

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

执行结果:

 4.完整的Demo

 1.main.c

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


int main(int argc, char *argv[]) {

    SeqStack S;
    int cmd,d,maxsize;
    DataType x;
    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("请选择(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)?");
                fflush(stdin);
                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:
                printf("确定要销毁(销毁后数据不可恢复,y|n,n)?");

                fflush(stdin);//  清空输入stdin缓冲区

                scanf("%c", &yn);
                if (yn == 'y' || yn == 'Y') {
                    if (!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;
        }

    } while (cmd != 0);

    return 0;
}

 2.seqstack.c

#include <stdio.h>
#include <malloc.h>
#include "seqstack.h"
#include <string.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;
}




/*十进制转换为二进制*/
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);
}

/*后缀表达式计算*/
void expression() {
    SeqStack S;
    int i,op1, op2,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 = op2 + op1;
                push(&S, x);
                break;

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

3.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);

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

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

5.小结 

顺序栈是数据结构中比较基础的一种数据结构,它是一种线性数据结构。采用先进后出的原则,类似于箱子叠放,后进的箱子需要先取出来,这就是顺序栈的特点。在学习顺序栈的过程中,掌握了顺序栈的创建、入栈、出栈等基本操作,同时也深刻理解了顺序栈数据结构的特性。

6.参考文献

《数据结构(c语言版)》李刚 刘万辉

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值