什么是栈?栈这种数据结构有什么样的特性?它能够拿来干嘛?本文我们将深度探讨,剖析清楚栈的全部,你让熟练掌握栈的运用!
栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
定长的静态栈,实际中我们一般不使用,所以我们下面主要实现的就是支持动态增长的栈 。
typedef int StackData;
typedef struct Stack
{
StackData* data;
int size;
int capacity;
}Stack;
对数据类型进行重命名,这样以后需要更换其他数据类型使用的时候只需要更改这一个地方就可以了。
定义一个数组动态的开辟空间,size用来存储当前栈内的有效元素个数,capacity来表示栈的总容量大小,这样的是为了当栈内有效元素个数与容量一致时,方便对其进行扩容。
void StackInit(Stack* SK)
{
assert(SK);
SK->data = NULL;
SK->capacity = 0;
SK->size = 0;
}
先将栈中所有的数据都初始化为空,因为栈只需要在容量满的时候进行扩容,这里可以不需要先开辟空间,这一步可以节省。
void StackPush(Stack* SK,StackData x)
{
assert(SK);
if (SK->capacity == SK->size)
{
SK->capacity = (SK->capacity == 0 ? 5 : SK->capacity * 2);
StackData* tmp = (StackData*)realloc(SK->data,sizeof(StackData) *SK->capacity);
if (tmp == NULL)
{
perror("realloc ");
exit(-1);
}
SK->data = tmp;
}
SK->data[SK->size] = x;
SK->size++;
}
在对栈进行数据插入前,首先进行栈区容量检查,如果满或是空,就先进行空间的增容。然后再将元素插入到栈顶,栈中有效元素个数size++。
void StackPop(Stack* SK)
{
assert(SK);
assert(SK->size > 0);
SK->size--;
}
栈的出栈相较入栈更为简单,因为栈的空间是动态开辟来的,无法对其一部分空间进行释放,故无法达到真正意义上的删除。这里也不可将元素的值置为0,因为有一种情况就是元素数据的值就是0。因此这里只需要让size–就可以达到目的,size是栈中有效的元素个数,插入元素时也是使用size为下标进行插入,所以size–后,代表栈少了一个元素,再进行入栈操作,新的元素就会覆盖旧的值。
StackData StackTop(Stack* SK)
{
assert(SK);
assert(SK->size > 0);
return SK->data[SK->size-1];
}
想要知道栈顶的元素,首先要对栈中元素进行判定,如果栈中元素不大于0,则栈中无元素。
栈有元素时,size是有效元素个数,数组的性质下标是从0开始,所以这里size-1,就代表栈的顶部元素。
bool StackEmpty(Stack* SK)
{
assert(SK);
return SK->size == 0;
}
在什么情况下栈为空?只有一种情况就是栈内的元素个数为0,此时站内无元素就是空。
int StackSize(Stack* SK)
{
assert(SK);
return SK->size;
}
当我们在对栈进行多次入栈和出栈操作后,我们想知道此时栈中还有多少元素时,就会用到。如何知道呢,在最开始我们定义了一个size,它存的值就是栈内的有效元素个数,所以只需要返回size就可以。
void StackDestroy(Stack* SK)
{
assert(SK);
free(SK->data);
SK->capacity = 0;
SK->size = 0;
SK->data = NULL;
}
这里不能直接对SK进行释放,因为SK中的data是动态开辟来的,所以需要先对data进行free,然后将其他成员置空。
栈作为一种数据结构,在计算机科学中具有广泛的泛用性,它可以应用于各种不同的问题和场景。
经过对归并排序的思想,特性,代码实现这些细致入微的讲解,相信聪明的你肯定已经学会了叭!
☁️ 好啦,由于篇幅有限,本章仅对栈进行了细致入微的讲解,后序还会有更多的数据结构文章分享哦!
看到这里了希望给博主留个:
点赞收藏 ⭐️ 关注!
❤️
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。