栈
栈是一种数据结构,也是一个特殊的线性结构,队列中的数据是先入先出类似于一个数据通道,栈中的数据是先入后出(FILO),我们可以想象向一个罐子中放入食物,食物的直径与罐子直径相同,由于底部是封闭的无法食物只能从罐口拿这样我们每次都只能拿到最上层的食物即最新放进去的食物,这就是栈存储数据的特性。
若是将栈比作存放食物的罐子,那么我们将罐口比作栈顶这是放入和取出食物或者数据的地方。我们将第一个数据放入的位置称为栈底,栈底是封闭,所以将数据放入栈中我们也称为压栈,将数据压在栈的底部。
数组栈
栈也是一个逻辑结构,需要使用实际的方法去实现,这里我们使用数组或是链表都是可以实现栈的,但是由于栈的特性,插入数据和取出数据是在同一个方向,即然对插入和删除都没有特别要求那我们使用数组就是很方便的,这里我们就介绍的数组的实现方式。
栈的创建和初始化
这里我们定义一个结构体方便对栈(数组)的管理,结构体中包含了数组的首地址指针,容量和有效数据个数。
动态开辟内存,初始我们给的4个数据的空间后期有需要再扩容以尽可能节省空间。这时的栈是没有数据的就将有效数据个数置0,容量置4完成创建和初始化。
对堆内空间判满和扩容
传入结构体的指针,对比容量和有效数据个数,若是相等证明堆内空间已经满了,进行扩容,我们使用realloc函数给原本的容量增大一倍。
入栈与出栈
因为栈的特性就是插入数据和取出数据是同一端,而数组最方便的就是尾插和尾删,对数组不需要任何的改动,所以我们将数组的尾部定为栈顶,数组的头就是栈底。删除就将有效数据个数减一,入栈直接将新数据赋给下标为有效数据个数的空间即可。
栈销毁
对于动态开辟出来的内存我们需要手动释放,再将结构体内的指针置空避免野指针。
完整代码
typedef int InnDate;//数组实现栈结构
typedef struct Inn//动态扩容的栈
{
InnDate* p;
int capacity;//容量
int size;//有效数据个数
}Inn;
void InitInn(Inn* head)//初始化栈
{
InnDate* tmp = (InnDate*)malloc(sizeof(InnDate)*4);//初始化4个空间
assert(tmp);
head->p = tmp;
head->capacity = 4;
head->size = 0;
tmp = NULL;
}
void DilaInn(Inn* head)//判断栈是否满,满了便扩容
{
if (head->capacity == head->size)
{
InnDate* tmp = (InnDate*)realloc(head->p, sizeof(InnDate)*head->capacity*2);//二倍扩容
assert(tmp);
head->p = tmp;
head->capacity *= 2;
tmp = NULL;
}
return;
}
void PushInn(Inn* head,InnDate n)//入栈
{
DilaInn(head);
head->p[head->size] = n;
(head->size)++;
}
void PopInn(Inn* head)//出栈
{
DilaInn(head);
(head->size)--;
}
void PrintInn(Inn* head)//打印栈从栈底开始
{
if (head->size == 0)
printf("栈为空\n");
else
printf("从栈底开始打印");
for (int i = 0; i < head->size; i++)
{
printf("%d ", head->p[i]);
}
printf("\n");
}
void PrintInn2(Inn* head)//从栈顶开始打印
{
if (head->size == 0)
printf("栈为空\n");
else
printf("从栈顶开始打印");
for (int i = head->size; i > 0; i--)
{
printf("%d ", head->p[i - 1]);
}
printf("\n");
}
InnDate GetTop(Inn * head)//获取栈顶元素
{
if (head->size == 0)
printf("栈为空\n");
return head->p[head->size - 1];
}
int GetSize(Inn* head)//获取有效数据个数
{
if (head->size == 0)
printf("栈为空\n");
return head->size;
}
void DestroyInn(Inn* head)//销毁栈
{
if (head->p == NULL)
return;
free(head->p);
head->p = NULL;
head->capacity = 0;
head->size = 0;
}//数组栈尾