目录
一.栈的定义
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
二.顺序栈
顺序栈是栈的顺序实现。顺序栈是指利用顺序存储结构实现的栈。采用地址连续的存储空间(数组)依次存储栈中数据元素,由于入栈和出栈运算都是在栈顶进行,而栈底位置是固定不变的,可以将栈底位置设置在数组空间的起始处;栈顶位置是随入栈和出栈操作而变化的,故需用一个整型变量top来记录当前栈顶元素在数组中的位置。
三.顺序栈的实现
1.初始化
/*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.进(入)栈
/*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.出栈
/*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.取栈顶元素
/*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.栈是否空
/*5.栈为空?*/
int empty(SeqStack *S){
return(S->top == -1) ? 1 : 0;
}
6.栈是否满
/*6.栈满?*/
int full(SeqStack *S){
return(S->top == S->maxsize - 1)? 1 : 0;
}
7.销毁栈
/*7.销毁*/
int destroy(SeqStack *S){
free(S->data);
return 0;
}
8.栈的应用
(1)十进制转换为二进制
/*十进制转换为二进制*/
int d_to_b(int d){
SeqStack S;
int b;
/*初始化栈*/
init(&S,32);
/*d不为0,余数进栈*/
while(d)
{
push(&S,d % 20);
d /= 2;
}
/*依次出栈*/
while (!empty(&S))
{
pop(&S,&b);
printf("%d",b);
}
/*销毁栈*/
destroy(&S);
}
(2)后缀表达式
/*后缀表达式计算*/
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,&op1);
x = op2 + op1;
push(&S,x);
break;
case '*':
pop(&S,&op1);
pop(&S,&op1);
x = op2 * op1;
push(&S,x);
break;
case '-':
pop(&S,&op1);
pop(&S,&op1);
x = op2 - op1;
push(&S,x);
break;
case '/':
pop(&S,&op1);
pop(&S,&op1);
x = op2 / op1;
push(&S,x);
break;
}
}
pop(&S,&x);
printf("计算结果为;%s = %d\n",exp,x);
destroy(&S);
}
四.运行结果
1.初始化
2.进(入)栈
3.出栈
4.取栈顶元素
5.栈是否空
6.栈是否满
7.销毁栈
8.栈的应用
(1)十进制转换为二进制
(2)后缀表达式
六.完整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",&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;
}
seqstack.c
#include <stdio.h>
#include <malloc.h>
#include <string.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;
}
/*十进制转换为二进制*/
int d_to_b(int d){
SeqStack S;
int b;
/*初始化栈*/
init(&S,32);
/*d不为0,余数进栈*/
while(d)
{
push(&S,d % 20);
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,&op1);
x = op2 + op1;
push(&S,x);
break;
case '*':
pop(&S,&op1);
pop(&S,&op1);
x = op2 * op1;
push(&S,x);
break;
case '-':
pop(&S,&op1);
pop(&S,&op1);
x = op2 - op1;
push(&S,x);
break;
case '/':
pop(&S,&op1);
pop(&S,&op1);
x = op2 / op1;
push(&S,x);
break;
}
}
pop(&S,&x);
printf("计算结果为;%s = %d\n",exp,x);
destroy(&S);
}
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 destory(SeqStack *S);
/*十进制转换为二进制*/
int d_to_b(int d);
/*后缀表达式计算*/
void expression();
七.小结
顺序栈:用一段连续的存储空间来存储栈中的数据元素。
顺序存储结构:1.元素所占的存储空间必须连续。
2.元素在存储空间的位置是按逻辑顺序存放的。
八.参考文献
栈----百度百科
顺序栈----百度百科
《数据结构(c语言版)》李刚 刘万辉