栈详解(C语言)

文章目录

  • 写在前面
  • [1 栈的定义](#1 栈的定义)
  • [2 栈的初始化](#2 栈的初始化)
  • [3 数据入栈](#3 数据入栈)
  • [4 数据出栈](#4 数据出栈)
  • [5 获取栈顶元素](#5 获取栈顶元素)
  • [6 获取栈元素个数](#6 获取栈元素个数)
  • [7 判断栈是否为空](#7 判断栈是否为空)
  • [8 栈的销毁](#8 栈的销毁)

写在前面

本片文章详细介绍了另外两种存储逻辑关系为 "一对一" 的数据结构------栈和队列中的栈,并使用C语言实现了数组栈。

栈C语言实现源码:栈源码

以栈在存储数据时具有特殊的顺序规则:
:使用栈结构存储数据,遵循"**先进后出"**的原则,即最先进栈的数据最后出栈。栈可以分为顺序栈(基于数组实现)和链栈(基于链表实现)。

栈的实现方式分为顺序和链式结构,分别适用于不同的场景。顺序结构在内存中占据一块连续的空间,而链式结构通过节点之间的指针连接。这使得栈和队列在实际应用中更灵活,可以根据具体需求选择不同的实现方式。

1 栈的定义

栈结构的定义通常包括一个动态开辟的数组,用来存储数据,一个用于记录栈顶位置以及一个用于记录栈容量的变量。下面是栈结构的定义:

c 复制代码
typedef int STDataType;

//数组栈
typedef struct Stack
{
	STDataType* nums;//动态开辟的数组
	int top;//栈顶位置
	int capacity;//栈容量
}Stack;

2 栈的初始化

刚开始栈是一个空栈,因此需要将栈的元素数组指针 nums 初始化为 NULL,表示栈中当前没有元素。capacity 表示栈的容量,初始时为0,表示栈中没有元素。而将top 初始化为0,表示top指向栈顶元素的下一个位置

代码如下:

c 复制代码
void StackInit(Stack* pst)
{
	assert(pst);//检查参数有效性
	pst->nums = NULL;

	pst->top = pst->capacity = 0;//top初始化为0,说明top指向栈顶元素的下一个位置
}

3 数据入栈

数据入栈的操作:

  1. 检查栈是否已满,如果满了要进行扩容操作。
  2. 根据上面栈的初始化操作,我们知道,top是指向栈顶元素的下一个位置,因此,数据入栈时,只需将数据放在top指向的位置,再将top向后移动一个位置即可。

图解如下:

代码如下:

c 复制代码
void StackPush(Stack* pst, STDataType x)
{
	assert(pst); //检查参数有效性
	//检查是否需要扩容
	if (pst->top == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->nums, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("StackPush->malloc");
			exit(-1);
		}
		pst->nums = tmp;
		pst->capacity = newcapacity;
	}
	//元素入栈
	pst->nums[pst->top++] = x;
}

4 数据出栈

我们知道,栈只能在栈顶一端出入数据,出数据时只能出栈顶的数据。

数据出栈的步骤如下:

  1. 在执行出栈操作之前,需要检查栈是否为空。如果栈为空(即没有数据),则无法执行出栈操作,因为没有数据可以出栈。
  2. 如果栈不为空,即存在数据,就可以执行出栈操作。调整栈顶指针 top,通过将 top 向前移动一个位置,实现了出栈操作(这里是数组栈,top指向栈顶元素的下一个位置)。

图解如下:

代码如下:

c 复制代码
void StackPop(Stack* pst)
{
	assert(pst);//检查参数有效性
	assert(!StackEmpty(pst));//为空不能进行删除

	//元素出栈
	pst->top--;
}

5 获取栈顶元素

取栈顶元素的步骤如下:

  1. 在执行取栈顶元素操作之前,需要检查栈是否为空。如果栈为空(即没有数据),则无法执行此操作。
  2. top指向栈顶元素的下一个位置,如要获取栈顶元素,因此只需返回top-1位置的元素即可。

代码如下:

c 复制代码
STDataType StackTop(Stack* pst)
{
	assert(pst);//检查参数有效性
	assert(!StackEmpty(pst));//为空不能取栈顶元素

	return pst->nums[pst->top - 1];
}

6 获取栈元素个数

栈的栈顶指针top是指向栈顶元素的下一个位置,同时top的值也是栈元素个数。

代码如下:

c 复制代码
int StackSize(Stack* pst)
{
	assert(pst);//检查参数有效性

	return pst->top;
}

7 判断栈是否为空

根据初始化栈的函数我们知道,当栈为空时,栈的栈顶指针top是指向nums数组的0位置。

代码如下:

c 复制代码
bool StackEmpty(Stack* pst)
{
	assert(pst);//检查参数有效性

	return pst->top == 0;
}

8 栈的销毁

根据栈结构的定义,我们知道,栈用来存储数据的数组,是动态申请的,因此栈在销毁时需要手动释放动态申请的空间,同时将top和capacity置为0。

代码如下:

c 复制代码
void StackDestroy(Stack* pst)
{
	assert(pst);//检查参数有效性

	free(pst->nums);

	pst->nums = NULL;
	pst->top = pst->capacity = 0;
}

至此,本片文章就结束了,若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。

创作不易,白嫖不好,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

如果本篇博客有任何错误,请批评指教,不胜感激 !!!

相关推荐
杨荧10 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
白子寰16 分钟前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
XuanRanDev25 分钟前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
代码猪猪傻瓜coding27 分钟前
力扣1 两数之和
数据结构·算法·leetcode
王俊山IT28 分钟前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
为将者,自当识天晓地。30 分钟前
c++多线程
java·开发语言
小政爱学习!32 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
神奇夜光杯1 小时前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue1 小时前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·