系列文章目录
数据结构_线性表_顺序表(C语言实现+超详细逐步解析-CSDN博客
数据结构_线性表_双向链表(C语言实现+基本操作-CSDN博客
目录
一、栈基本概念、结构、图示
栈的逻辑结构:
可以类比一个“羽毛球筒”,最先进入的羽毛球,必须等待,其他球取出,才能出来。
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。
进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。(如图所示:)
栈的物理结构:
可以用数组实现,也可以用链表实现。
二、栈的基本操作
1、初始化
数组的结构实现更优一些。因为数组在尾插的代价比较小。
创建栈的结构体,包括栈的基本信息,数组,栈顶,栈的容量。
代码:
创建栈
typedef struct Stack {
SDataType* st;//动态开辟
int top;//栈顶
int capacity;//容量
}ST;
初始化栈
!!!注意
top 的取值,
第一种,top = 0,则栈顶元素在 top - 1 的位置
第二种,top = -1,则栈顶元素在 top 的位置。
在本文中,top 取值为 0
// 初始化栈
void StackInit(ST* s) {
assert(s);
// 栈 s 不能为空
//assert的作用是现计算表达式 test,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。
s->st = NULL;
s->top = s->capacity = 0;
}
2、入栈
注意事项:
1、栈满、栈空时,都需要对栈的空间进行扩容,使用realloc函数。
空间开辟的规则,一般遵循,一开始开辟四个单位。
后面扩容时,扩增为原来的2倍。
2、动态开辟问题
检查是否开辟成功。
使用完毕后,也必须使用free函数,释放掉。避免内存泄漏。
// 入栈
void StackPush(ST* s, SDataType data) {
assert(s);
int newcapacity;//新容量
//栈满 栈空 条件判断
//则需要开辟新空间,
//栈空开辟 4个
//栈满 开辟原先的 2倍
if (s->capacity == s->top) {
//栈空
if (s->capacity == 0) {
newcapacity = 4;
}
else newcapacity = s->capacity * 2; //栈满
SDataType* temp = (SDataType*)realloc(s->st,sizeof(SDataType) * newcapacity);
//扩容
//检查是否扩容成功
if (temp == NULL) {
perror("malloc failed");
exit(-1);
}
s->st = temp;
s->capacity = newcapacity;
}
s->st[s->top] = data;
s->top++;
}
3、出栈
// 出栈
void StackPop(ST* s,SDataType* data) {
assert(s);
if (s->top == 0) {
printf("栈空");
}
data = s->st[s->top - 1];
s->top--;
}
4、栈顶元素
栈顶元素在 top - 1 的位置
// 获取栈顶元素
SDataType StackTop(ST* s) {
assert(s);
assert(s->top > 0);//栈不为空
return s->st[s->top - 1];
}
5、栈中有效元素个数
// 获取栈中有效元素个数
int StackSize(ST* s) {
assert(s);
return s->top ;
}
6、检测栈是否为空
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(ST* s) {
assert(s);
if (s->top == 0) {
return 1;
}
else return 0;
}
7、销毁栈
// 销毁栈
void StackDestroy(ST* s) {
assert(s);
free(s->st);
s->st = NULL;
s->top = s->capacity = 0;
}
三、汇总
本篇文章就到此结束啦!
以下就是全篇汇总啦~
#include"Stack.h"
// 初始化栈
void StackInit(ST* s) {
assert(s);
// 栈 s 不能为空
//assert的作用是现计算表达式 test,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。
s->st = NULL;
s->top = s->capacity = 0;
}
// 入栈
void StackPush(ST* s, SDataType data) {
assert(s);
int newcapacity;//新容量
//栈满 栈空 条件判断
//则需要开辟新空间,
//栈空开辟 4个
//栈满 开辟原先的 2倍
if (s->capacity == s->top) {
//栈空
if (s->capacity == 0) {
newcapacity = 4;
}
else newcapacity = s->capacity * 2; //栈满
SDataType* temp = (SDataType*)realloc(s->st,sizeof(SDataType) * newcapacity);
//扩容
//检查是否扩容成功
if (temp == NULL) {
perror("malloc failed");
exit(-1);
}
s->st = temp;
s->capacity = newcapacity;
}
s->st[s->top] = data;
s->top++;
}
// 出栈
void StackPop(ST* s,SDataType* data) {
assert(s);
if (s->top == 0) {
printf("栈空");
}
data = s->st[s->top - 1];
s->top--;
}
// 获取栈顶元素
SDataType StackTop(ST* s) {
assert(s);
assert(s->top > 0);//栈不为空
return s->st[s->top - 1];
}
// 获取栈中有效元素个数
int StackSize(ST* s) {
assert(s);
/*因为top是指向栈顶元素的最后一个位置
假设元素为:1,2,3,4,5,那么top肯定是指向5的后一个位置
又因为top是从0开始累加的,所以此时top肯定为5,刚好就是元素个数
*/
return s->top ;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool StackEmpty(ST* s) {
assert(s);
if (s->top == 0) {
return 1;
}
else return 0;
}
// 销毁栈
void StackDestroy(ST* s) {
assert(s);
free(s->st);
s->st = NULL;
s->top = s->capacity = 0;
}