你真的会数据结构吗:栈

本文介绍了计算机科学中栈的概念,数据结构中的栈原理(LIFO),并探讨了用链表(包括单链表和双向链表)和数组实现栈的优缺点,最终选择了数组方法作为示例,并提供了C语言代码实现。
摘要由CSDN通过智能技术生成

❀❀❀ 文章由@不准备秃的大伟原创 ❀❀❀

♪♪♪ 若有转载,请联系博主哦~ ♪♪♪

❤❤❤ 致力学好编程的宝藏博主,代码兴国!❤❤❤

         铁汁们,我又回来了,不知道大家有没有想我呢?哈哈,大伟现在的学校的课是真的很多啊,完全不能和上学期相比,之后的周一和周五基本都没有时间来更新博客了,希望大家理解哈~╮(╯▽╰)╭更何况这一周是第一周,实在是有给大伟累到,所以本次的博客:栈,就会相对简单也更短一些了,不过大家也不要停止学习啊(╯ε╰) 

        之前的数据结构我们谈论了链表的两种:单链表和双向链表,不知道大家有没有理解呢?不过数据结构对于我们这种新手来说确实难了一点,但是大伟相信,只要我们付出相对应的时间,我们终有一天会变成大牛的!(ง •_•)ง

        好的,话不多说了,我们开始今天的学习吧:栈。

        那么在写代码之前,我们先来了解一下数据结构里面的栈是什么:

      在计算机科学中,栈(Stack)是一种数据结构,它遵循先进后出(Last In, First Out,LIFO)的原则。这意味着最后进入栈的元素是第一个被取出的,而最先进入栈的元素是最后被取出的。栈可以看作是一种容器,只能在容器的一端(称为栈顶)进行插入和删除操作,另一端(称为栈底)是固定的。

栈有两个主要的基本操作:

  1. 压入(Push):将元素添加到栈顶。
  2. 弹出(Pop):从栈顶移除元素。

        如上,我们知道了栈是遵循LIFO的原理的,那我们该如何实现呢?我们有两个思想:

  1. 联想之前的链表,用链表的结构实现栈
  2. 不知道大家还记不记得,我们一开始在学习单链表的时候,当时也有两个备选方案:1.就是我们现在沿用的一次开一个空间的方法  2.是定义一个定长的数组,然后再进行扩容,没错,就是顺序表

        那我们该用那种呢,我们来分析一下:

         如果我们选用链表的方法,每次压入元素就创建一个空间(节点),每次删除元素就释放一个空间,而为了释放尾节点的空间,我们是不是就需要一个tail(尾节点)的指针,而且需要一个prev来链接两个空间,综上,我们该使用哪种链表?  没错,就是双向链表,然后我们再思考其他的方面是不是也觉得没问题?好,就觉得是你了,双向链表!

        诶,等等,别这么猴急啊~ (~ ̄▽ ̄)~ ,不知道大家有没有觉得就为了实现一个尾部的增添而选用双向链表太浪费(麻烦)了? 于是我们再来分析一下数组的方法:

        如果我们选用数组的方法,假如我们初始给了四个空间,我们就会需要一个top节点来记录数组存放最后一个有效数据的坐标,一个capacity来记录当前数组的总大小,如果要压入元素就直接在当前的top的下一个下标位置放入元素,如果要弹出元素就直接top减一(当然前提是空间足够)

        诶,这样一对比无论是从思维还是从代码量方面都是选择数组更好一点,那么,开码吧! 

        老规矩:Stack.c     Stack.h     test.c  

        Stack.h

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top; // 栈顶
	int capacity; // 容量 
}Stack;
// 初始化栈 
void StackInit(Stack* ps);
// 入栈 
void StackPush(Stack* ps, STDataType data);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);

        Stack.c

                初始化:

void StackInit(Stack* ps)
{
	assert(ps);

	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

                压入:

void StackPush(Stack* ps, STDataType data)
{
	assert(ps);

	if (ps->capacity == ps->top)
	{
//扩容
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("malloc fail");
			return;
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
//给值
	ps->a[ps->top++] = data;
}

                弹出:

void StackPop(Stack* ps)
{
	assert(ps);
//若栈为空
	assert(!StackEmpty(ps));

//不需要改变值,因为已经没用了
	ps->top--;
}

                判断栈是否为空:

int StackEmpty(Stack* ps)
{
	assert(ps);
//若top为0,则返回true,否则返回false
	return ps->top == 0;
}

                取栈顶元素:

STDataType StackTop(Stack* ps)
{
	assert(ps);
//若栈为空
	assert(!StackEmpty(ps));

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

                栈的大小:

int StackSize(Stack* ps)
{
	assert(ps);
	return ps->top;
}

                摧毁栈

void StackDestroy(Stack* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

          解决了,是不是很简单?诶,先别着急,玩一玩?٩(͡๏̯͡๏)۶

        test.c

int main()
{
	Stack s;
	StackInit(&s);
	StackPush(&s, 1);//1
	StackPush(&s, 2);//1 2
	int top = StackTop(&s);//top = 2
	printf("%d ", top);//2
	StackPop(&s);//1

	StackPush(&s, 3);//1 3

	
	top = StackTop(&s);//3
	printf("%d ", top);//3
	StackPop(&s);//1

	top = StackTop(&s);//1
	printf("%d ", top);//1

	return 0;
}

bfe7e6fa01bf4b769b56e2856613f4d1.png

        可以看到,我们的代码是没有什么问题龙图,如果大家还有别的想要测试的话,自己私下实现哦~

        到这里本篇博客已经可以是完结了,但是接着栈后面就是队列了,下篇文章我会对大家介绍,请大家继续支持大伟,谢啦!!☆⌒(*^-゜)v 

         A bird in the hand is worth two in the bush. 双鸟在林不如一鸟在手。

         本篇博客也就到此为止了,送大家一碗鸡汤,勉励自己以及这世界上所有追逐梦想的赤子趁年华尚好努力提升自己,莫欺少年穷!  86aa131099ac4f7cb1100915abb39f9f.jpeg

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大伟听风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值