数据结构-顺序栈

1.顺序栈的定义

1.1 在了解顺序栈之前,我们要先知道栈是什么。

操作受限的线性表,限定仅在表尾进行插入和删除操作的线性表,即后进先出。这一端被称为栈顶,相对地,把另一端称为栈底。

栈的特点;

① 后进先出LIFO。

② 类比:洗碗盘子 子弹弹夹子弹出列。

1.2 顺序栈

用顺序结构存储的栈。

是限定仅在表尾进行插人或删除操作的线性表。因此,对栈来说,表尾端有其特殊含义,称为栈顶,相应地,表头端称为栈底。不含元素的空表称为空栈。栈的修改是按后进先出的原则进行的,因此栈又称为后进先出的线性表,简称LIFO结构。而顺序栈就是使用顺序结构来实现栈,顺序栈的空间是连续分配的。

2.顺序栈的基本运算

顺序栈的6种基本运算如下:

①初始化为栈空 InitStack(S):初始化操作,构造一个空栈。

②进栈操作 Push (S,x):进栈操作。在栈的顶部插入一个新元素x。

③出栈操作 Pop (S):出栈操作。删除栈顶端元素,并返回该元素。

④取栈顶元素 StackTop(S):取栈顶元素。返回栈顶元素,但不删除。

⑤判断栈是非为空 StackEmpty(S):判断栈是否为空。若栈为空,函数返回值为1;否则,返回值为0。

⑥判断栈是否为满 StackFull (S):判断栈是否为满。若栈已满,函数返回值为1;否则,返回值为0。

⑦销毁

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

运行结果: 

十进制转二进制 

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(&amp;S, exp[i] - 48);
                break;
            case '+':
                /*出2个*/
                pop(&amp;S, &amp;op1);
                pop(&amp;S, &amp;op2);
                x = op2 + op1;
                push(&amp;S, x);
                break;
            case '*':
                pop(&amp;S, &amp;op1);
                pop(&amp;S, &amp;op2);
                x = op2 * op1;
                push(&amp;S, x);
                break;
            case '-':
                pop(&amp;S, &amp;op1);
                pop(&amp;S, &amp;op2);
                x = op2 - op1;
                push(&amp;S, x);
                break;
            case '/':
                pop(&amp;S, &amp;op1);
                pop(&amp;S, &amp;op2);
                x = op2 / op1;
                push(&amp;S, x);
                break;
        }
    }
    pop(&amp;S, &amp;x);
    printf("计算结果为:%s = %d\n", exp, x);
    destroy(&amp;S);
}

 

4.完整demo

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", &amp;cmd);
        switch (cmd) {
            case 1:
                printf("请输入栈的最大存储空间(MaxSize):");
                scanf("%d", &amp;maxsize);
                if (!init(&amp;S, maxsize)) {
                    printf("栈已初始化!\n");
                }
                break;
            case 2:
                printf("请输入入栈元素:x=");
                scanf("%d", &amp;x);
                if (!push(&amp;S, x)) {
                    printf("元素【%d】已入栈!\n", x);

                }
                break;
            case 3:
                printf("确定要出栈(出栈后数据不可恢复,y|n,n)?");
                fflush(stdin);
                scanf("%c", &amp;yn);
                if (yn == 'y' || yn == 'Y') {
                    if (!pop(&amp;S, &amp;x)) {
                        printf("栈顶元素【%d】已出栈!\n", x);
                    }
                }

                break;
            case 4:
                if (!get_top(&amp;S, &amp;x)) {
                    printf("栈顶元素为:%d\n", x);
                }
                break;
            case 5:
                if (empty(&amp;S)) {
                    printf("栈为空!\n");
                } else {
                    printf("栈不为空!\n");
                }
                break;
            case 6:
                if (full(&amp;S)) {
                    printf("栈已满!\n");
                } else {
                    printf("栈未满!\n");
                }
                break;
            case 7:
                printf("确定要销毁(销毁后数据不可恢复,y|n,n)?");
                fflush(stdin);//  清空输入stdin缓冲区
                scanf("%c", &amp;yn);
                if (yn == 'y' || yn == 'Y') {
                    if (!destroy(&amp;S)) {
                        printf("销毁栈成功!\n");
                    }
                }
                break;
            case 8:
                do {
                    printf("----------8.栈的应用------------\n");
                    printf(" 1. 十进制转换为二进制\n");
                    printf(" 2. 后缀表达式计算\n");
                    printf(" 0. 返回\n");
                    printf("请选择:");
                    scanf("%d", &amp;cmd);

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

                    if (cmd == 2) {
                        expression();
                    }
                } while (cmd != 0);
                cmd = -1;
                break;
        }

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

seqstack.c

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

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

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

    /*d不为0,余数进栈*/
    while (d) {
        push(&amp;S, d % 2);
        d /= 2;
    }

    /*依次出栈*/
    while (!empty(&amp;S)) {
        pop(&amp;S, &amp;b);
        printf("%d", b);
    }

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

/*后缀表达式计算*/
void expression() {
    SeqStack S;
    int i,op1, op2,x;

    char exp[20]; /*后缀表达式*/
    init(&amp;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(&amp;S, exp[i] - 48);
                break;
            case '+':
                /*出2个*/
                pop(&amp;S, &amp;op1);
                pop(&amp;S, &amp;op2);
                x = op2 + op1;
                push(&amp;S, x);
                break;

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

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

/* 8.十进制转二进制*/
int d_to_b(int d);

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

5.小结

萌新初学,如有错误,欢迎指出。

6.参考文献

《数据结构(C语言版)》

知乎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值