写有“售后”的博客:一定回复评论和私信,答疑解惑到底,认真探讨大家的疑问,欢迎大家多多指出批评与建议。
一、栈的简介

栈就像一个一端封闭的羽毛球筒,添加/删除数据就像放入/拿出羽毛球
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中数据元素遵循“先入后出”(“后入先出”)原则
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
出栈:栈的删除操作叫做出栈,出数据也在栈顶
二、顺序栈的基本操作
相关的头文件
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
#pragma once防止头文件被重复包含
<assert.h>是assert断言的头文件
<stdlib.h>是动态内存空间开辟函数以及free释放的头文件
<stdbool.h>是布尔类型头文件
定义顺序栈结构体
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
栈中存放的数据可能变为各种类型,我们为了修改方便使用typedef 类型 STDataType;
STDataType* a; 用于存放栈的各个元素,指针形式便于动态扩容
top指向栈顶数据的下一个数据(初始指向0)/指向栈顶数据(初始指向-1)
capacity表示栈的空间大小
栈的初始化
void STInit(ST* pst)
{
assert(pst);
pst->a = NULL;
pst->top = pst->capacity = 0;
}
为了让形参的改变影响实参,我们使用传址调用,实参传地址,那么我们形参用指针接收
函数接收指针后都要判断指针是否为空,本文我们都用assert断言判断
我们的top初始化为0,说明我们让top指向栈顶数据的下一个数据
栈的销毁
void STDestory(ST* pst)
{
assert(pst);
free(pst->a);
pst->a = NULL;
pst->top = pst->capacity = 0;
}
检查栈是否需要动态扩容
void STCheckCapacity(ST* pst)
{
assert(pst);
if (pst->top == pst->capacity)
{
int newcapacity = pst->capacity == 0 ? 4 : 2 * pst->capacity;
STDataType* temp = (STDataType*)realloc(pst->a,newcapacity*sizeof(STDataType));
if (temp == NULL)
{
perror("realloc");
return ;
}
pst->a = temp;
pst->capacity = newcapacity;
}
}
top指向栈顶数据的下一个数据,相当于size表示数据个数,最开始时,栈顶数据在-1位置,top和capacity都在0位置,0个数据占据0个空间,入栈需要动态扩容。易知每当top==capacity时,都需要动态扩容
使用三目操作符,需要动态扩容时,若capacity为0则变为4,不为零则变为二倍的capacity
使用realloc函数改变空间大小,pst->a为NULL时,realloc相当于malloc。使用中介temp而非a直接接收realloc的返回值,防止realloc函数返回空造成原空间的丢失
入栈
void STPush(ST* pst, STDataType x)
{
assert(pst);
STCheckCapacity(pst);
pst->a[pst->top] = x;
pst ->top++;
}
入栈需判断是否需要动态扩容
若top初始指向-1,应该先++,再插入数据
出栈
void STPop(ST* pst)
{
assert(pst);
assert(pst->top > 0);
pst->top--;
}
出栈需确保栈内有数据,即top大于0
获取栈顶数据
STDataType STTop(ST* pst)
{
assert(pst);
assert(pst->top > 0);
return pst->a[pst->top-1];
}
获取数据也要确保栈内有数据,即top大于0
避雷return pst->a[ pst->top-- ];的写法,-- 是先执行后减减,相当于获取该栈顶数据的下一个数据后再删除该数据,不仅越界访问,还给我出栈了。
判断栈是否为空
bool STEmpty(ST* pst)
{
assert(pst);
return pst->top == 0;
}
获取数据个数
int STSize(ST* pst)
{
assert(pst);
return pst->top;
}
完。

被折叠的 条评论
为什么被折叠?



