数据结构:栈

一种特殊的线性表,其只允许在固定的一段进行插入和删除,其中进行插入和删除的一段叫做栈顶,另一端叫做栈底,其中数据元素遵循后进先出的原则,允许数据插入的一段叫做栈顶,另一端叫做栈底,栈的底层逻辑就是先进后出

我们用图片来更好的理解进出栈

我们可以联想前面学过的顺序表链表和数组,栈可以类比哪一种来实现呢?

先看数组:从栈顶依次输出,并且size--,数组作为栈实现的底层逻辑最方便的一点就是,给定的一块空间我们可以不需要再进行额外的申请空间内存来实现元素的进出,那么空间复杂度为O(1),我们可以在开始就对增容一次,realloc*2

接着我们考虑一下单链表,我们要做到空间复杂度为O(1),只能进行头插和头删,注意一点,我们在进行头删的时候将头结点phead向后移动一位,并将之前第一块空间释放


~~~~小结一下~~

栈是属于线性表的一种,既然属于线性表,那就符合线性表的存储结构,分为顺序存储和链式存储,对于顺序结构实现栈的操作时,最后一个进栈的也是数组的最后一个位置,用于增添和删除,讲到这里,我们要格外注意,栈不能够通过遍历来实现数据的打印,也不可以往中间位置插入数据和删除数据

二、栈的实现(含码源)👓👓👓

1.库头文件

#include "Stack.h"
#include <stdio.h>
#include<assert.h>  //断言,检查是否为真
#include <stdlib.h> //relloc的头文件,用于增容
#include<stdbool.h> //用于判空的头文件

2.结构体定义(头文件)

typedef int STDataType;
typedef struct Stack
{
	STDataType* arr;
	int capacity;
	int top;
}ST;

3.初始化

初始化栈,将指向栈的变量的地址传递过来用一级指针来接受,初始化,就是将其指针置空,空间大小以及栈顶置为0即可。

//初始化
void STInit(ST*ps)
{
	assert(ps);
	ps -> arr = NULL;
	ps->capacity = ps->top = 0;
}

4.功能实现

5.出栈   入栈 以及扩容操作

详细解读:在上述的代码中,一个大前提就是capacity空间大小必须要大于我们的栈顶及有效数据的个数,我们首先要进行判断使用if判断语句判断是否相等,重新定义一块儿叫作newcapacity的空间,如果初始值为零,就将它赋为4个字节的大小,反之即将原来的空间大小扩为二倍。

对于数组arr要进行空间大小的申请,我们采用realloc来进行扩容,也就是实现动态开辟空间。那我们也比较一下malloc的增容,对于空间开辟的越来越大,realloc可以实现放弃掉旧的位置,在开辟一块空间,将旧空间的数据和内存保存复制到新的空间内,并将旧的空间和内存释放掉。用realloc增容,通常是到自身大小的两倍或者三倍。若是频繁的增容会使性能降低。

最后进行数组arr开辟空间的一个判空,若tmp为空,直接结束函数并打印错误信息。反之将tmp赋值给ps->arr,最后我们便可以放心的在栈顶插入元素,最后将栈顶ps->top++

6.判空以及出栈的打印

对与测试text.c文件

对于stack.c文件来说,我们来写一下判空的函数以及去栈顶元素的函数


//取栈顶元素
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

		return ps->arr[ps->top - 1];
}

​
//出栈
void StackPop(ST*ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	--ps->top;

}

top为栈里面的有效数据个数,取出栈顶元素,对应的top-1即可

这里还有一个判空的函数需要额外注意一下,我们重新封装成一个新的函数,一直出栈,知道栈为空将停止出栈,不等于空,为真,继续执行

bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

7.获取栈的元素个数

int STSize(ST* ps)
{
   asset(ps);
   return ps->top;
}

8.销毁

void STDestroy(ST*ps)
{
    assert(ps);
    if(ps->arr)
        free(ps->arr);
    ps->arr=NULL;
    ps->capacity=ps->top= 0;
}

  


🥇结语

通过本篇文章的学习,您应该掌握了栈的基本概念和创建方法,栈对于后续的算法题目中提供了一个很好的思想,在许多编程场景中都有广泛的应用,希望通过这些知识,您能够更好地理解和运用栈,感谢您的阅读,期待在下一篇文章中继续与您探讨更多有趣的数据结构和算法。

  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值