栈
栈的定义
- 栈是一个后进先出(Last In Fist Out, LIFO)的线性表,是特殊的线性表,包括顺序栈、链栈。但它是操作受限的线性表,即只能在表尾进行插入和删除操作
- 对于栈来说,表尾称为栈顶(top),表头称为栈底(bottom)
- 栈的插入操作叫做进栈(Push),也称为压栈、入栈
- 栈的删除操作叫做出栈(Pop),也称为弹栈
- 不含元素的空表为空栈(top==base)
顺序栈
顺序栈为栈的顺序存储结构,动态分配一维数组的存储空间,封装了base,top,stacksize
- 栈底指针base,指向栈底的指针变量,即一维数组的数组名
- 栈顶指针top,指向栈顶的指针变量,非空栈的top始终指向栈顶元素的下一个位置。
- stacksize是栈的分配的存储空间,即最大容量
- 当base值为NULL时,表示栈不存在
- 空栈标志为top==base
- 随机存取栈中的元素,下标从0开始,第i个元素为S->base[i-1]
//-----栈的顺序存储结构-----
#define STACK_INIT_SIZE 100//顺序栈的存储空间初始分配量
#define STACK_INCREMENT 10//顺序栈存储空间的分配增量
typedef struct
{
ELemType *base;//栈底指针,可作为一维数组名使用
ELemType *top;//栈顶指针,指向栈顶元素的下一个位置
int stacksize;//栈的最大容量,即分配的存储空间
}
初始化空栈
- 动态分配一维数组的存储空间,由base指针指向该数组
- 设置栈顶指针Stop指向栈底,当前为空栈
- 设置栈的最大容量stacksize
//-----初始化化,创建一个空栈-----
bool InitStack(SqStack *S)
{
//动态分配一维数组的存储空间
S->base=(ELemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));
if(S->base==NULL) return false;//存储分配失败
S->top=S->base;//设置栈顶指针,当前栈为空
S->stacksize=STACK_INIT_SIZE;//设置栈的最大容量
return true;
}
取栈顶元素
判断栈是否为空栈
//-----顺序栈,取栈顶元素-----
bool SqStack_gettop(SqStack *S,ElemType *e)
{
//判断栈是否为空栈
if(S->top==S->base) return false;//空栈
*e=(S->top-1)//取栈顶元素
return true;
}
入栈(插入元素)
判断栈是否已满,已满则追加空间
//-----顺序栈,入栈元素e-----
bool Push(SqStack *S,ElemType e)
{
//判断栈是否已满
if(S->top-S->base>=S->stacksize)//栈满,追加空间
{
ElemType *newbase=(ElemType *)realloc((S->stacksize+STACK_INCREMENT)*sizeof(ElemType));
if(newbase==NULL) return false;//存储分配失败
S->base=newbase;
S->top=S->base+S->stacksize;//设置栈顶指针
S->stacksize+=STACK_INCREMENT;//设置栈的最大容量
}
*S->top=e;//入栈
S->top++;//栈顶指针后移
}
出栈(删除元素)
判断栈是否为空
//-----顺序栈,出栈,返回值e-----
bool Pop(SqStack *S,ElemType *e)
{
//判断栈是否为空
if(S->top==S->base) return false;
S->top--;//出栈,栈顶指针前移
*e=*S->top;//返回值
return true;
}
栈的当前容量
//-----计算栈当前所用的容量-----
int SqStack_len(SqStack *S)
{
return S->top-S->base;
}
清空栈
-
清空一个栈,是将栈中的元素值作废,但栈本身物理空间并不释放(不是销毁)
-
只要让S->top=S->base即可,表明这个栈为空。与高级格式化只是清空文件列表而没有覆盖硬盘的原理是一样的,只是逻辑上清空了一个栈。
//-----清空顺序栈-----
void SqStack_clear(SqStack *S)
{
S->top=S->base;
}
销毁栈
销毁一个栈,要释放栈所占的内存空间
//-----销毁顺序栈-----
void SqStack_destroy(SqStack *S)
{
int len=S->stacksize; //当前栈中的元素个数
for(int i=0;i<len;i++)
{
free(S->base); //循环释放栈所占的物理内存空间
S->base++; //栈底指针上移
}
s->base = s->top = NULL;
s->stacksize = 0;
}
链栈
栈的链式存储结构,即操作受限的链表,操作省略