一、栈的概念
- 栈是只能在固定的一端进行插入和删除操作的受限线性表。
- 进行插入删除操作的一端叫做栈顶,另一端叫做栈底。
- 栈的插入操作:入栈(进栈、压栈),入数据在栈顶。
- 栈的删除操作:出栈,出数据也在栈顶。
- 栈的特性:后进先出(Last In First out,LIFO),符合这个特性的问题就可以考虑使用栈来解决。,比如括号匹配、后缀表达式求值。
二、栈的基本操作
- 初始化一个栈
- 销毁栈
- 入栈操作
- 判断栈是否为空,后续的出栈和取栈顶元素都需要在栈非空情况下实现。
- 出栈操作
- 取栈顶元素
栈的实现可以用数组(顺序栈)或链表(链式栈)实现,这里选择用动态数组实现。
三、栈的实现
1.栈声明Stack.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int STDataType;
//定义栈的结构
typedef struct Stack
{
STDataType* arr; //动态分配栈的空间,底层是数组
int top;//栈顶,始终指向栈顶位置(其实相当于顺序表的size,改个名字),有效数据个数
int capacity; //栈的容量
}ST;
//初始化
void STInit(ST* ps);
//销毁
void STDestroy(ST* ps);
//栈插入和删除只能在栈顶
//入栈
void STPush(ST* ps, STDataType x);
//判断栈是否为空,出栈和取栈顶元素都要在栈非空的情况下才能操作
bool STEmpty(ST* ps);
//出栈--栈顶
void STPop(ST* ps);
//取栈顶元素
STDataType STTop(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
2.栈实现Stack.c
#include "Stack.h"
//初始化
void STInit(ST* ps)
{
assert(ps);
ps->arr = NULL;
//在这里将top和capacity分开赋值
//方便后续使用C++的缺省函数来实现空间分配
//当我们知道具体要多少空间时直接传参,不知道就用默认参数。
ps->capacity = 0;
ps->top = 0;
}
//销毁
void STDestroy(ST* ps)
{
assert(ps);
if (ps->arr) //记得判断!!!
{
free(ps->arr);
}
ps->arr = NULL;
ps->capacity = 0;
ps->top = 0;
}
//栈插入和删除只能在栈顶
//入栈
void STPush(ST* ps, STDataType x)
{
assert(ps);
//空间不够--增容
//"=="才是等于
if (ps->capacity == ps->top)
{
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
STDataType* temp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));
if (temp == NULL)
{
perror("realloc is fail!");
exit(1);
}
ps->arr = temp;
ps->capacity = newCapacity;
}
ps->arr[ps->top++] = x;
}
//判断栈是否为空
//返回值是bool类型
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
//出栈--栈顶
void STPop(ST* ps)
{
assert(!STEmpty(ps));
--ps->top;
}
//取栈顶元素
STDataType STTop(ST* ps)
{
assert(!STEmpty(ps)); //栈为空,不能取元素
return ps->arr[ps->top - 1];
}
//获取栈中有效元素个数
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
3.测试test.c
#include "Stack.h"
void test();
int main()
{
test();
return 0;
}
void test()
{
ST st;
STInit(&st);
STPush(&st, 1);
STPush(&st, 2);
STPush(&st, 3);
STPush(&st, 4);
STPush(&st, 5);
/*STPop(&st);
STPop(&st);
STPop(&st);
STPop(&st);*/
while (!STEmpty(&st))
{
//取栈顶元素
STDataType top = STTop(&st);
printf("%d ", top);
STPop(&st);
}
printf("\n");
STDestroy(&st);
}