1、基本概念
栈(Stack)是一种遵循后进先出(LIFO, Last In First Out)原则的有序集合。这种数据结构只允许在栈顶进行添加(push)或删除(pop)元素的操作。栈的底部称为栈底,栈顶则是指允许添加或删除元素的那一端。
2、实现方式
栈可以通过数组或链表来实现。
-
基于数组的栈:使用数组来存储栈中的元素,通常需要一个变量来记录栈顶的位置。当执行push操作时,将新元素添加到数组的末尾,并更新栈顶位置;pop操作则是移除数组末尾的元素,并相应地调整栈顶位置。如果栈的大小超过了数组的容量,则可能需要动态地调整数组的大小。
-
基于链表的栈:使用链表来存储栈中的元素,链表的头部即为栈顶。push操作相当于在链表头部插入新节点;pop操作则是移除链表头部的节点。链表实现的栈在动态调整大小方面通常比数组实现更为灵活,但访问链表元素的时间复杂度可能较高。
3、数组栈实现
(1)定义
typedef int STDataType;
typedef struct Stack
{
STDataType* a;//数组
int top;//栈顶位置
int capacity;//数组容量
}ST;
(2)初始化
//初始化
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;//先给值,再++ ps->top = -1;先++,再给值
ps->capacity = 0;
}
(3)销毁
//销毁
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
(4)插入(栈顶)
//栈顶插入
void StackPush(ST* ps,STDataType x)
{
assert(ps);
if(ps->top == ps->capacity)
{
//扩容
int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType)*newCapacity);//realloc对已有空间进行增容
if(tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
//更新数据
ps->a = tmp;
ps->capacity = newCapacity;
}
//插入数据
ps->a[ps->top] = x;
(ps->top)++;
}
(5)删除(栈顶)
//栈顶删除
void StackPop(ST* ps)
{
assert(ps);
//assert(ps->top > 0);栈不为空
assert(!StackEmpty(ps));
ps->top--;
}
(6)取栈顶数据
//取栈顶数据
STDataType StackTop(ST* ps)
{
assert(ps);
//assert(ps->top > 0);栈不为空,栈为空所取值为a[-1],越界访问,是个随机值
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
(7)栈存放数据多少
//栈存放数据多少
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
(8)栈是否为空
//判断栈是否为空
bool StackEmpty(ST* ps)
{
assert(ps);
/*
if(tps->top == 0)//为空
{
return ture;
}
else//不为空
{
return false;
}
*/
return ps->top == 0;
}
4、测试用例
main.c
#include <stdio.h>
#include <stdlib.h>
#include "Stack.h"
void TestStack()
{
ST st;
StackInit(&st);
//栈顶插入
StackPush(&st,5);
StackPush(&st,7);
StackPush(&st,8);
StackPush(&st,11);
printf("%d,%d ",StackSize(&st),StackTop(&st));
//栈顶删除
StackPop(&st);
StackPop(&st);
StackPop(&st);
StackPop(&st);
//StackPop(&st);
StackDestroy(&st);
}
void Test1Stack()
{
ST st;
StackInit(&st);
//栈顶插入
StackPush(&st,1);
StackPush(&st,2);
StackPush(&st,3);
StackPush(&st,4);
//出栈
printf("%d ",StackTop(&st));
StackPop(&st);
printf("%d ",StackTop(&st));
StackPop(&st);
//栈顶插入
StackPush(&st,5);
StackPush(&st,6);
//出栈,只能从栈顶出
while(!StackEmpty(&st))
{
printf("%d ",StackTop(&st));//取出栈顶数据
StackPop(&st);//删除当前栈顶数据,取下一个数据
}
//坚持一个原则:后进先出(LIFO)
StackDestroy(&st);
}
int main(int argc, char *argv[])
{
//TestStack();
Test1Stack();
return 0;
}