3.C_数据结构_栈

news2024/9/17 7:44:10

概述

什么是栈:

栈又称堆栈,是限定在一段进行插入和删除操作的线性表。具有后进先出(LIFO)的特点。

相关名词:

  • 栈顶:允许操作的一端
  • 栈底:不允许操作的一端
  • 空栈:没有元素的栈

栈的作用:

  • 可以检测逻辑图中是否有回路
  • 可以将非线性问题线性化 

入栈与出栈示意图:

入栈:先指针+1,再入栈数据。出栈:先出栈数据,再指针+1

顺序栈

1、基本内容

顺序栈就是以数组形式进行存储的栈数据结构。

顺序栈结构体如下:

typedef int data_t;
typedef struct{
	data_t* pData;//数据
	int max_len;  //最大数据长度
	int top;      //栈顶位置
}sqstack,*stacklink;

顺序栈代码的文件构成:

  • sqstack.h:数据结构的定义、运算函数接口
  • sqstack.c:运算函数接口的实现
  • test.c:使用数据结构实现的应用功能代码

顺序栈相关函数:

1、整个栈的创建和删除

  • 创建:stacklink stack_create(int len);
  • 删除:int stack_delete(stacklink pStack);

2、入栈、出栈

  • 入栈:int stack_push(stacklink pStack,data_t data);
  • 出栈:int stack_pop(stacklink pStack,data_t* data);

3、其他

  • 栈清空:int stack_clean(stacklink pStack);
  • 判断栈是否为空:int stack_isempty(stacklink pStack);

2、功能实现  

2.1 创建/删除栈

2.1.1 创建 

创建栈与创建线性表一样,都是先申请空间,之后赋值初始值

注意:在申请栈成功后,如果申请数据空间失败,需要释放申请的栈空间 

具体代码实现如下:

/*
 * stack_create:创建一个栈
 * param len:栈的长度
 * @ret NULL--err  other--栈的地址
 * */
stacklink stack_create(int len){
	
	stacklink pStack = NULL;
	//1.申请空间
	//1.1 栈的空间
	pStack = (stacklink)malloc(sizeof(sqstack));
	if(pStack == NULL){
		printf("stack malloc err\n");
		return NULL;
	}
	//1.2 数据的空间
	pStack->pData = (data_t*)malloc(sizeof(data_t)*len);
	if(pStack->pData == NULL){
		printf("data malloc err\n");
		free(pStack);//此时pStack已经申请成功,应该释放空间
		return NULL;
	}
	//2.初始化
	memset(pStack->pData,0,sizeof(data_t)*len);
	pStack->max_len = len;
	pStack->top = -1;//-1代表空栈

	return  pStack;
}
2.1.2 删除

 删除栈就是释放所申请的空间。

注意:这里申请的空间是栈空间和数据空间,所以要释放两次

具体代码实现如下: 

/*
 * stack_delete:栈的释放
 * param pStack:要进行释放的栈
 * @ret  -1--err 0--success
 * */
int stack_delete(stacklink pStack){
	//1.判断栈空间是否为空
	if(pStack == NULL){
		printf("pStack is NULL\n");
		return -1;
	}
	//2.释放空间
	free(pStack->pData);//释放数据空间
	free(pStack);       //释放栈空间
	pStack = NULL;
	return 0;
}

2.2 入栈与出栈

2.2.1 入栈

入栈就是先将指针+1,再将数据入栈。

具体代码实现如下:

/*
 * stack_push:入栈
 * param pStack:所需入栈的栈的位置
 * param data:所需入栈的数据
 * @ret  -1--err  0--success
 * */
int stack_push(stacklink pStack,data_t data){
	//1.判断栈空间是否为空
	if(pStack == NULL){
		printf("pStack is NULL\n");
		return -1;
	}
	//2.判断栈空间是否已满
	if(pStack->top == (pStack->max_len-1)){
		printf("stack is full\n");
		return -1;
	}
	//3.入栈
	pStack->top++; 					    	//栈顶移动
	*(pStack->pData + pStack->top) = data;  //数据入栈
	return 0;
}
2.2.2 出栈

入栈就是先将数据出栈,再将指针-1。

具体代码实现如下:

/*
 * stack_pop:出栈
 * param pStack:要进行出战的栈的位置
 * param data:出栈数据存储的位置
 * @ret  -1--err  0--success
 * */
int stack_pop(stacklink pStack,data_t* data){
	//1.判断栈空间是否为空
	if(pStack == NULL || data == NULL){
		printf("pStack is NULL\n");
		return -1;
	}
	//2.判断栈是否为空栈
	if(pStack->top == -1){
		printf("stack is empty\n");
		return -1;
	}
	//3.出栈
	*data = *(pStack->pData + pStack->top);//数据出栈
	pStack->top--; 						 //顶部移动
	return 0;
}

2.3 其他

2.3.1 栈清空

栈清空就是让栈的指针指向-1。

栈情况并不需要清空数组中的数据,因为之后写入新数据会自动覆盖旧数据

具体代码实现如下:

/*
 * stack_clean:清空栈
 * param pStack:要进行清空的栈
 * @ret  -1--err  0--success
 * */
int stack_clean(stacklink pStack){
	//1.判断栈空间是否为空
	if(pStack == NULL){
		printf("pStack is NULL\n");
		return -1;
	}
	//2.清空栈
	pStack->top = -1;//设为空栈不需要清空
	return 0;
}
2.3.2 判断栈是否为空

空栈就是指针指向-1。

具体代码实现如下:

/*
 * stack_isempty:判断栈是否为空栈
 * param pStack:需要进行判断的栈
 * @ret  -1--err  1--空栈  0--非空栈
 * */
int stack_isempty(stacklink pStack){
	//1.判断栈空间是否为空
	if(pStack == NULL){
		printf("pStack is NULL\n");
		return -1;
	}
	if(pStack->top == -1){
		return 1;
	}else{
		return 0;
	}
}

链式栈

1、基本内容

链式栈就是以链表形式进行存储的栈数据结构。

链式栈结构体如下:

typedef int data_t;
typedef struct node{
	data_t data;  		//数据
	struct node* pNext;  //链表指针
}listnode,*stacklink;

链式栈代码的文件构成:

  • linkstack.h:数据结构的定义、运算函数接口
  • linkstack.c:运算函数接口的实现
  • test.c:使用数据结构实现的应用功能代码

链式栈相关函数:

1、整个栈的创建和删除

  • 栈结点创建:stacklink stacknode_create(void);
  • 删除:int stack_delete(stacklink* pStack);

2、入栈、出栈

  • 入栈:int stack_push(stacklink* pStack,data_t data);
  • 出栈:int stack_pop(stacklink* pStack,data_t* data);

2、功能实现  

2.1 创建/删除栈

2.1.1 栈结点创建

使用链式栈时,不是一次性创建一整个栈,而是有一个数据入栈就创建一个栈的结点。

具体代码实现如下:

/*
 * stacknode_create:创建栈结点
 * @ret  NULL--err  other--栈的地址
 * */
stacklink stacknode_create(void){
	
	stacklink pStack = NULL;
	//1.申请空间
	pStack = (stacklink)malloc(sizeof(listnode));
	if(pStack == NULL){
		printf("malloc err\n");
		return NULL;
	}
	//2.初始化
	memset(pStack,0,sizeof(listnode));
	pStack->pNext = NULL;
	return pStack;
}
2.1.1 删除整个栈

删除整个栈就是释放全部的申请空间。

具体代码实现如下:

/*
 * stack_delete:释放整个栈
 * param pStack:要进行删除的栈
 * @ret  -1--err  0--success
 * */
int stack_delete(stacklink* pStack){
	stacklink point = *pStack;
	//1.栈空间判断
	if(*pStack == NULL){
		printf("pStack is NULL\n");
		return -1;
	}
	//2.释放空间
	while(point != NULL){
		point = point->pNext;
		free(*pStack);
		*pStack = point;
	}
	*pStack = NULL;
	return 0;
}

2.2 入栈与出栈

2.2.1 入栈

链式栈的入栈就是创建一个新结点,并把这个结点进行头插,这样出栈时每次访问头就可以实现后进先出的特点。

具体代码实现如下:

/*
 * stack_push:入栈,头插法
 * param pStack:要进行插入的栈
 * param data:要入栈的数据
 * @ret  -1--err  0--success
 * */
int stack_push(stacklink* pStack,data_t data){
	stacklink pTmp = NULL;
	//1. 开辟新的结点
	pTmp = stacknode_create();
	if(pTmp == NULL){
		return -1;
	}
	pTmp->data = data;
	//2.开始入栈,
	//2.1 有栈空间,进行头插
	if(*pStack != NULL){
		pTmp->pNext = *pStack;
	}
	//2.2 没有栈空间,当前结点就是头
	*pStack = pTmp;//最终都要把头指向最新的结点

	return 0;
}
2.2.2 出栈

链式栈的出栈就访问链表的头,访问之后将头部结点进行删除。

具体代码实现如下:

/*
 * stack_pop:出栈,取出链表头并释放空间
 * param pStack:要进行出栈的栈
 * param data:出栈的数据存放的位置
 * @ret  -1--err  0--success
 * */
int stack_pop(stacklink* pStack,data_t* data){
	stacklink pTmp = NULL;
	//1.栈空间判断
	if(*pStack == NULL){
		printf("pStack is NULL\n");
		return -1;
	}
	//2.开始出栈
	*data = (*pStack)->data;//出栈数据
	pTmp = (*pStack)->pNext;
	free(*pStack);//释放空间
	*pStack = pTmp;//改变链表头
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2116467.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【机器人工具箱Robotics Toolbox开发笔记(一)】Matlab机器人工具箱简介

MATLAB是一款被广泛应用于科学计算和工程领域的专业软件。它的全称为Matrix Laboratory(矩阵实验室),因为其最基本的数据类型就是矢量与矩阵,所以在处理数学和科学问题时非常方便,可用于线性代数计算、图形和动态仿真的…

系统架构的演进:同步通讯到异步通讯的过渡

系统架构的演进:同步通讯到异步通讯的过渡 一 . 同步通讯 VS 异步通讯1.1 同步调用方案① 耦合度高② 性能下降③ 资源浪费④ 级联失败 1.2 异步调用方案① 同步解耦② 性能提升 , 吞吐量增加③ 服务没有强依赖 , 不必考虑级联失败问题④ 流量削峰 1.3 小结 二 . 三…

【C++】STL学习——stack和queue的讲解(了解适配器)

目录 stack介绍queue介绍适配器stack的模拟实现queue模拟实现deque(了解) stack介绍 stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行 元素的插入与提取操作。stack是作为容器适配器被…

Java | Leetcode Java题解之第393题UTF-8编码验证

题目&#xff1a; 题解&#xff1a; class Solution {static final int MASK1 1 << 7;static final int MASK2 (1 << 7) (1 << 6);public boolean validUtf8(int[] data) {int m data.length;int index 0;while (index < m) {int num data[index];…

算法练习题18——leetcode240搜索二维矩阵||(二分)

题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 代码 class Solution {public boolean searchMatrix(int[][] matrix, int target) {for(int[…

双指针(6)_单调性_查找总价格为目标值的两个商品

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 双指针(6)_单调性_查找总价格为目标值的两个商品 收录于专栏【经典算法练习】 本专栏旨在分享学习C的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#…

DuPL: Dual Student with Trustworthy Progressive Learning for Robust WSSS

摘要 近年来&#xff0c;具有图像级标签的单阶段弱监督语义分割(WSSS)因其简化了其繁琐的多阶段语义分割而获得了越来越多的关注。由于类激活图(Class Activation Map, CAM)固有的模糊性&#xff0c;我们观察到一级管道经常会遇到由错误的CAM伪标签引起的确认偏差&#xff0c;…

基于SpringBoot的图书馆座位预约系统+小程序+LW参考示例

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

继电器的使用

本文为大家讲一下继电器的常规使用. 添加 在菜单中选择 “绘制–无源元件–添加继电器(relay)” 以添加继电器. 或者用 shiftr(大写) 这个快捷键 继电器由一个线圈和该线圈所控制的铁质弹性开关(衔铁)组成. 原理 它的原理如下: 上面的铁质弹性开关, 默认情况下在弹力作用下…

java基础概念22-抽象类

一、抽象类的引入 1-1、封装 问题&#xff1a;javabean越来越多。重复的内容越多——继承 1-2、继承 二、抽象类、抽象方法 一个方法抽取到父类中&#xff0c;不确定方法体——抽象方法 定义了抽象方法的类——抽象类。 在Java中&#xff0c;抽象类是一种特殊的类&#xff0c…

博士生锻炼记录:2024.9.8

读博三年来感觉身体状况大不如前&#xff0c;虽然博士生的主要任务就是做课题和发文章&#xff0c;但是身体健康也是不容忽视的一环&#xff0c;一个好的身体是做好任何事情的基础&#xff0c;我们应该在不影响身体健康的前提下努力做课题。 这周初去参加了一个体成分测量的活…

Python编码系列—Python项目管理:掌握高效工具与实践

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

YOLOv9改进策略【Neck】| 使用CARAFE轻量级通用上采样算子

一、本文介绍 本文记录的是利用CARAFE上采样对YOLOv9的颈部网络进行改进的方法研究。YOLOv9采用传统的最近邻插值的方法&#xff0c;仅考虑子像素邻域&#xff0c;无法捕获密集预测任务所需的丰富语义信息&#xff0c;从而影响模型在密集预测任务中的性能。CARAFE通过在大感受…

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包&#xff0c; 通常我们会使用nohup直接启动&#xff0c;但是还是需要手动停止然后再次启动&#xff0c; 那如何更优雅的在服务器上启动jar包呢&#xff0c;让我…

设计模式之工厂模式(通俗易懂--代码辅助理解【Java版】)

文章目录 1、工厂模式概述1&#xff09;特点&#xff1a;2&#xff09;主要角色&#xff1a;3&#xff09;工作流程&#xff1a;4&#xff09;优点5&#xff09;缺点6&#xff09;适用场景 2、简单工厂模式(静态工厂模式)1) 在简单工厂模式中&#xff0c;有三个主要角色&#x…

基于SpringBoot的宠物服务系统+uniapp小程序+LW参考示例

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

浏览器插件利器--allWebPluginV2.0.0.20-alpha版发布

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品&#xff0c;致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX控件直接嵌入浏览器&#xff0c;实现插件加载、界面显示、接口调用、事件回调等。支持Chrome、Firefo…

小琳AI课堂:深入学习BERT

大家好&#xff0c;这里是小琳AI课堂。今天我们来聊聊BERT&#xff0c;这个在自然语言处理&#xff08;NLP&#xff09;领域掀起革命风潮的模型。 出现背景 在BERT之前&#xff0c;NLP领域主要依赖RNN或CNN模型&#xff0c;这些模型大多只能单向处理文本&#xff0c;从左到右…

【全网首创】大模型LLM-RAG知识库问答项目实战课

在大数据和人工智能迅猛发展的今天&#xff0c;大模型和知识库的结合成为了理论探索和实际应用的重要方向。LLM-RAG项目课程正是围绕这一热点展开&#xff0c;旨在通过系统性的教学&#xff0c;帮助学员掌握从项目部署、模块开发到实际应用的完整流程。课程共有43课时&#xff…

SprinBoot+Vue公交智能化系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…