栈的定义
----------------------------------------------
定义:栈是一个后进先出(Last in first out,LIFO)的线性表,它要求只在表尾进行删除和插入操作
特点:1.栈的元素必须要后进先出
2.栈的操作只能在线性表的表尾进行
3.栈的表尾称为栈的栈顶(top),相应的表头称为栈底(bottom)
4.表头==栈底,表尾==栈顶
5.栈顶是高地址,栈底是低地址
栈的插入(push),进栈、压栈、入栈
栈的删除(pop),出栈、弹栈
栈的存储形式:顺序存储结构和链式存储结构,一般应用栈的顺序存储结构
最开始栈中不含任何数据,叫做空栈,此时栈顶就是栈底,数据从栈顶进入,栈顶栈底分离,整个栈的当前容量变大,
数据出栈时从栈底弹出,栈顶下移,整个栈的当前容量变小
顺序存储结构
----------------------------------------------
定义:typedef struct
{
ElemType *base; //栈底指针变量
ElemType *top; //栈顶指针变量
int stackSize; //栈当前可用的最大容量
}sqStack;
创建栈
#define STACK_INIT_SIZE 100 //栈的最大容量
initStack(sqStack *s){
s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType)); //调用函数malloc申请空间
if( !s->base ) exit(0); //申请空间失败,异常判断
s->top = s->base; //初始状态栈底就是栈顶
s->stackSize = STACK_INIT_SIZE; //栈当前可用的最大容量
}
入栈
入栈操作又叫压栈操作,就是向栈中存放数据。
入栈操作要在栈顶进行,每次向栈中压入一个数据,top指针+1,直到栈满为止
code:
-----------
#include <stdio.h>
#include <stdlib.h>
#define SATCKINCREMENT 10 //追加空间量
Push(sqStack *s, ElemType e){
/*如果栈满追加空间*/
if(s->top - s->base >= s->stackSize){
s->base = (ElemType *)relloc(s->base,(s->stackSize + SATCKINCREMENT) * sizeof(ElemType)); //使用relloc函数追加空间,将原存储单元中的数据复制到新建的更大存储单元中
if( !s->base ) exit(0);
s->top = s->base + s->stackSize; //设置栈顶==栈底+当前栈空间的容量
s->stackSize = s->stackSize + SATCKINCREMENT; //设置栈的最大容量,栈的当前容量+扩容容量
}
*(s->top) = e; //向栈中放入数据
s->top++; //当有数据放入时,栈顶增加
}
出栈
出栈操作就是在栈顶取出数据,栈顶指针随之下移,每取出一个数据,栈的当前容量-1
栈顶不存放数据,取出的数据为栈顶的下一个数据
栈为空的时候,top=-1
code
-----------
Pop(sqStack *s, ElemType *e){
if(s->top == s->base) return 0; //空栈
*e = *--(s->top); //栈顶不存放数据,取出的数据为栈顶的下一个数据
}
清空栈
只需要将s->top的内容赋值给s->base
原理与高级格式化单纯清空文件列表而没有覆盖硬盘的原理一样
清空栈其本身的物理空间不发生改变,数据仍然存在
code
-----------
ClearStack(sqStack *s){
s->top = s->base;
}
销毁栈
与清空栈不同,需在在存储存储单元中彻底销毁,释放所占用的空间
code
-----------
DestoryStack(sqStack *s){
int i,len;
len = s->stacksize; //获取栈的容量
for(i = 0; i < len; i++){
free( s->base ); //从栈底(低地址)处开始释放空间
s->base++;
}
s->base = s->top = NULL;
s->stacksize = 0;
}
计算栈的当前容量