一、什么是栈?
- 栈是限制在一端进行操作(插入、删除)的线性表;
- 我们俗称为堆栈;
- 只不过是一种特殊的线性表,有顺序栈、也有链式栈
二、栈的特点
- 具有先进后出的特点,即先进栈的数据后出栈(LIFO);
- 入栈出栈可交替进行;
对于特点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;
}
#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;}