目录
栈的定义
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈:栈的删除操作叫做出栈。出数据也在栈顶。
简单来说:栈是遵循后进先出原则的线性表
物理线性和理论线性
既然规定了栈为一种特殊的线性表那么它一定是理论线性的
那它是否是物理线性呢?
这时需要插一段原地扩容与异地扩容的知识
先看下面这段代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
//异地扩容
int* p1 = (int*)malloc(8);
printf("%p\n", p1);
int* p2 = (int*)realloc(p1, 800);
printf("%p\n",p2);
//原地扩容
int* a1 = (int*)malloc(8);
printf("%p\n", a1);
int* a2 = (int*)realloc(a1, 8);
printf("%p\n",a2);
}
同样都是realloc扩容为什么p1指针扩容完成后地址发生了变化而a1却没有改变呢?
原来扩容并非真正的连续,如果要扩的空间比较大,而原来的空间别其他程序占用导致不足,就会重新开辟一片地区
但实际上数组还是连续的只是位置发生了变换
接下来的栈就是这样的道理
栈空间不足时会开辟新的空间而此时可能会导致地址的变换,但是数组却依然连续
这种情况称之为理论线性物理非线性
栈的创建
typedef struct Stack
{
STDataType* a;
int top; //栈顶
int capacity; //容量
}ST;
初始化和销毁
// 初始化和销毁
void STInit(ST* pst)
{
assert(pst);
pst->a = NULL;
// top指向栈顶数据的下一个位置
pst->top = 0;
// top指向栈顶数据
//pst->top = -1;
pst->capacity = 0;
}
void STDestroy(ST* pst)
{
assert(pst);
free(pst->a);
pst->a = NULL;
pst->top = pst->capacity = 0;
}
入栈 出栈
void STPush(ST* pst, STDataType x)
{
assert(pst);
// 扩容
if (pst->top == pst->capacity)
{
int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
pst->a = tmp;
pst->capacity = newcapacity;
}
pst->a[pst->top] = x;
pst->top++;
}
void STPop(ST* pst)
{
assert(pst);
assert(pst->top > 0);
pst->top--;
}
增添功能
// 取栈顶数据
STDataType STTop(ST* pst)
{
assert(pst);
assert(pst->top > 0);
return pst->a[pst->top - 1];
}
// 判空
bool STEmpty(ST* pst)
{
assert(pst);
return pst->top == 0;
}
// 获取数据个数
int STSize(ST* pst)
{
assert(pst);
return pst->top;
}
本文结束