数据结构-栈(理解版)

数据结构(C语言第2版) 课后习题答案 详细汇总 数据结构(C语言第2版) 课后习题答案之第一章绪论 数据结构(C语言第2版) 课后习题答案之第二章 线性表 数据结构(C语言第2版) 课后习题答案之 第三章 栈和队列 数据结构(C语言第2版) 课后习题答案之第四章 串、数组和广义表 数据结构(C语言第2版) 课后习题答案之第五章 树和二叉树 数据结构(C语言第2版) 课后习题答案之 第六章 图 数据结构(C语言第2版) 课后习题答案之 第七章 查找 数据结构(C语言第2版) 课后习题答案之 第八章 排序 ... 阅读详情

一、栈的定义

相信大家对于栈或多或少有一些了解,可能大多数人会告诉你栈是一种先进后出的数据结构。这其实说了跟没说一样(❁´◡`❁)!当然(last in,first out)是栈最有特色的性质。

这里可以给大家一些比较好理解的例子,像男生对枪械感兴趣的,不难发现:弹夹其实就是一个先进后出的容器,压入子弹后,先打出去的一定是最后压入的。同理,第一枚压入的子弹一定是最后打出的。

再比如,我们在浏览网页时,经常会有回退(即回到上一个浏览的网页)这一操作,那么同样不难想象,第一次回退操作的结果肯定是回到,除当前页面最后浏览的,而并不是第一个浏览的网页,这同样是先进后出的典型代表。

接下来我们展开讲一讲怎么将后进先出抽象出来。这里我们先回顾一下线性表的插入和删除操作,先找到插入位置的前驱结点,然后做指针或数组下标的相关操作。那么栈只不过是将操作对象局限为最后一个结点罢了。

那么其实总结起来说,栈还就只是一种后进先出的容器罢了,更简单明了地说,栈的本质还是一种顺序表,不过是只能在其一端进行插入和删除操作的特殊线性表。

那么就会有很多人问,既然栈的本质还是一种线性表,那我们为什么还要去重新定义这样一种数据结构呢?直接在线性表的基础上进行数组下标或者是链表指针的操作不就行了。首先我想说这是一个好问题,因为我也有这样的疑问。但是大家想一下,我们既然有了数组,为什么还要有顺序表呢?因为大家清楚顺序表本质就是一个数组。其实这就涉及到程序设计的问题,我们当然希望在编写程序的时候关注的问题越少越好,所以栈这个数据结构的创建就使得程序设计时的思考范围变小了,可以不需要去花精力考虑类似于数组下标等问题。

二、理解并手撕栈

头文件及宏定义

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

#define elemtype int
#define initcapacity 10
#define increment 10

initcapacity:初始化栈时的最大容量。

increment:在后面栈满后对空间进行再分配时,栈的最大空间的增量。

栈的定义

(这里以顺序栈为例,后期会更新其他实现:链栈、队列栈)

typedef struct Stack{
	elemtype *base;
	elemtype *top;
	int stacksize;
} Stack;

结构体中定义了两个elemtype类型的指针(*top、*base),然后是栈的最大容量stacksize。其中*top指向栈顶,*base指向栈底,所以由栈的LIFO特性可以知道,所有的操作都是在top一端进行的。

初始化栈(initStack)

Stack* initStack(){
	Stack *s=(Stack*)malloc(sizeof(Stack));
	s->base=(elemtype*)malloc(sizeof(elemtype)*initcapacity);
	s->top=s->base;
	s->stacksize=initcapacity;
	return s;
}

初始化时,当然是先要定义结构体Stack *s,然后将结构体中的元素(*top、*base)分配空间,而空间的长度就是宏定义的initcapacity。最后还要更新一下s->stacksize。

(ps:此处可以给s->base分配,再将其赋给s->top,也可以反过来,没有区别)

(ps:函数返回值是*Stack,当然也可以传入*Stack指针然后再进行初始化。)

销毁栈(destroyStack)

void destroyStack(Stack *s){  
	free(s->base);            
	s->base=NULL;      
	s->top=NULL;
	s->stacksize=0;          
}   

这里进行的操作是,先对结构体中的s->base进行free()操作,然后将其指针指置空。最后更新s->stacksize=0。

这里大家可能也会有问题,为什么只free(s->base),不用free(s->top)?

这里要简单解释一下free()函数的机制,我们输入由动态分配的内存的首地址,然后函数会将自定计算这块内存的长度,然后将其设置为可分配状态,最后由操作系统释放掉。而我们这里的首地址是s->base,s->top并不是首地址,所以应该释放掉s->base。

这里可能大家还会有疑惑,既然是将栈销毁,为什么不直接free(s),也就是直接将结构体释放掉,这样难道不是更方便吗?

首先我们要明确销毁栈的目的是什么?应该是,在我不需要这个栈时,我希望这一块空间被释放掉,也就是可被再分配。

那么如果直接将释放结构体,那么在结构体中动态分配的内存(也就是s->base)是无法释放的,这也就会导致内存泄漏,与我们的目的就不符了。

清空栈(clearStack)

void clearStack(Stack *s){
	s->top=s->base;
	s->stacksize=0; 
} 

清空栈比较简单,我只需要将将top指针重置为base就可以了。

(ps:这种方式的清空并不是真正意义上的将栈中元素删除了,它其实是一种清空的假象,栈的物理结构并没有改变,只不过那些没有删去的元素不用再去访问它了,在我要入栈时就会覆盖掉那些元素)

!!!如果有强迫症的话,可以将每一个元素删除 (^///^)。

压栈(pushStack)

void pushStack(Stack *s,elemtype e){
	if(s->top - s->base >= s->stacksize){
		s->base=(elemtype*)realloc(s->base,sizeof(elemtype)*(initcapacity+increment));
		if(!s->base){
		printf("fail realloc\n");
		exit(0);
		}
		s->top=s->base+s->stacksize;
		s->stacksize+=increment;
	}
	*s->top=e;
	s->top++;
}

其实压栈的核心操作就是两行代码:

*s->top=e;

 s->top++;

 另一大坨主要是考虑扩容和代码健壮性的校验代码:

s->base=(elemtype*)realloc(s->base,sizeof(elemtype)*(initcapacity+increment));

值得注意的是如果不熟悉realloc()函数,要注意一下该函数的输入,两个参数,(原内存首地址,再分配后的内存空间总数) ,然后进行强制类型转换。

弹栈(popStack)

void popStack(Stack *s){
	if(s->top==s->base){
		printf("stack is empty\n");
		exit(0);
	}
	printf("pop-%d\n",*(--s->top));
} 

弹栈的操作比较简单,先判断是否为空栈,然后将顶部元素弹出。这里需要注意的是s->top,并不是头部元素,一般情况下它是空的,等待着要入栈的元素。所以弹出的元素应该是,--s->top指向的元素。

(ps:s->top是一个指针,要输出值的话,是*s->top)

栈长度、顶部元素获取

int lengthStack(Stack *s){
	return s->top - s->base;
}

elemtype GetTop(Stack *s){
	return *(s->top-1);   //时刻记住s->top,是一个指针,要取值的话,加*!!!
}

这里涉及到的知识带是,指针可以相减获得两指针的距离:

s->top - s->base;

同样,这里需要注意栈顶元素是*(s->top-1)。

遍历栈(traverseStack)

void traveraeStack(Stack *s){
	if(s->base==s->top){
		printf("Stack is empty!\n");
		exit(0);
	}
	int len=lengthStack(s);
	
	for(int i=1;i<=len;++i){
		printf("%d->",*(s->top-i));  
	}                                
	printf("end\n");                 
}                                    

这里在遍历的时候也有一个小细节,不能直接写 *--(s->top),因为*s是作为指针传入的,这样会修改结构体中s->top的值,那么遍历结束后s->top就会与s->base重合了!!!此时再进行遍历就会是空栈!!!

运行结果

没有bug!!! 

三、写在最后

其实栈的实现逻辑是很简单的,就抓住栈的LIFO特性就可以了,后面的学的队列也是这样。

今天是以顺序栈为例分析的,其实还有链表实现栈,队列实现栈,以及以栈为基础的双端栈,这些数据结构都会之后的博客中,我都会写到。然后文章有什么问题的话,希望大家能够帮忙指正!

然后源代码已经上传到下面了,有需要的可以自取。

顺序栈(源码)

数据结构——栈 栈是一种数据结构,今天我们先来理解下栈的定义,然后再看几个在现实开发中运用到的实例。 1. 什么是栈? 栈是一个具有“先进后出、后进先出”这种特点的数据结构。 从栈的结构图中可以看出,栈是一种“操作受限”的线性表,只允许在一端插入或删除数据。 从功能上来说,数组或链表可以替代栈,但特定的数据结构是对应特定场景的抽象。当某个数据集合只涉及在一端插入和删除数据,并且满足先进后出、后进先出的特性时... 阅读详情

相关推荐

算法与数据结构【30天】集训营——栈和队列课后习题详解之C语言严蔚敏版(第二版)(08)

在拼数过程中,若遇非数字字符,表示数已拼完,将数压入栈中,并且将变量 num 恢复为 0,准备下一个数。解释:对于非循环队列,尾指针和头指针的差值便是队列的长度,而对于循环队列, 差值可能为负数, 所以需要将差值加上 MAXSIZE(本题为 n),然后与 MAXSIZE (本题为 n) 求余,即( n+r-f)%n。解释:栈是后进先出的线性表,一个栈的入栈序列是 1, 2, 3,, , n,而输出序列的 第一个元素为 n,说明 1,2,3,, , n 一次性全部进栈, 再进行输出, 所以。

迷茫与徘徊只会让你陷入绝境,欢迎私信博主,带你开始提升变现价值! 835

【数据结构-栈】对栈的理解逻辑都在这了(图文版)

1.栈(堆栈)简介 2.栈包含的特性以及基本运算 3.基于数组的栈逻辑运算 4.基于链表的栈逻辑运算 1.1栈(堆栈)简介 栈(stack)也被称为堆栈,是一种受限运算的线性表,是一组相同数据类型的组合。它添加和删除元素都被限制在表的一端进行(栈顶端),而另外一端则被称为栈底。 栈中的元素以后进先出(Last In First Out, LIFO)的方式进出栈,它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)

qq_58803118的博客 1572

深入理解数据结构与Java实现(第二版)

链表是一种线性数据结构,其中每个元素都是单独的对象,且包含指向下一个元素的指针。链表的类型根据指针的不同可以分为单向链表、双向链表和循环链表。单向链表的节点只包含指向下一个节点的指针,双向链表的节点则包含指向前一个节点和下一个节点的指针,而循环链表的最后一个节点指向第一个节点,形成一个闭环。

weixin_42160645的博客 1141

java版数据结构:深入理解栈和队列:数据结构与应用(vector,stack,queue)

数据结构中的动态数组,栈,队列,双端队列的基础知识

2303_80025768的博客 1474

严蔚敏数据结构(C版)配套光盘:全面实践指南

C语言是计算机程序设计中广泛使用的语言之一,以其简洁、高效、功能强大的特点被广大开发者所喜爱。学习C语言,首先要掌握它的基本语法,包括变量、数据类型、运算符、控制语句等。变量与数据类型变量是存储数据的基本单位,必须先定义后使用。C语言提供了多种数据类型,如int整型、char字符型、float单精度浮点型、double双精度浮点型以及void类型等。例如:// 定义了一个整型变量number,并初始化为10// 定义了一个字符型变量letter,并初始化为字符'A'运算符。

weixin_42513209的博客 701

清华大学版数据结构习题精讲与实战

本文还有配套的精品资源,点击获取 简介:数据结构是提升数据处理效率的关键,清华大学版的习题集提供了深入学习该领域理论与实践的资源。该习题集覆盖了线性结构、栈队列、树结构、图结构、排序与查找以及文件结构等关键知识点,通过系统性的习题练习,帮助学习者深化理解数据结构的原理和应用,提高软件设计与编程实践能力。 1.1 线性结构的定义与特点 在计算机科学中,线性结构...

weixin_31860973的博客 1232

数据结构 栈

基本讲解 可以把栈理解成一个放那种很大很重的书的箱子,每本书的长宽和箱子的尺寸一样,每当向这个箱子放书的时候,第一本是放到最底下的,然后依次往上放,每次取书的时候,都是从上往下取的,这也就是“先进后出”。 算法的基本原理 就是用一个Object数组来充当栈的内容,再定义栈顶指针,一个栈底指针。每次压栈的时候就元素放到数组[栈顶指针]的位置,每次出栈的时候就把数组[栈顶指针]的值弹出来就可...

weixin_39452731的博客 78

5分钟搞定PettingZoo多智能体环境搭建:从安装到运行第一个Demo

本文详细介绍了如何在5分钟内完成PettingZoo多智能体环境的搭建,从安装到运行第一个Demo。通过精准的版本控制和常见问题解决方案,帮助开发者快速上手多智能体强化学习(MARL)环境配置,并提供了实战案例和性能优化技巧。

backprop5master的博客 223

数据结构实验2《基于栈的中缀算术表达式求值》

(visual studio 2019可运行) 输入及输出要求见《数据结构C语言(第二版)》严蔚敏版 【本文仅用于啥都看不懂还想交作业选手】 #include <iostream> #include <stdlib.h> #include <cstring> #include<iomanip>//该头文件为了后面的输出保留两位小数 #define MAXSIZE 100//初始分配的存储空间 #define OK 1 #define OVERFLOW -2

Madelena的博客 3041

单细胞测序数据整合

基于Seurat 联合harmony进行单细胞数据整合分析

G2530051386的博客 9793

【嵌入式Linux】EC20模块多运营商自适应PPP拨号实战:从IMSI识别到网络配置

本文详细介绍了在嵌入式Linux系统中,如何基于EC20 4G模块实现多运营商自适应PPP拨号。通过解析SIM卡的IMSI识别运营商,并动态配置对应的APN和拨号参数,结合AT指令交互与健壮的pppd脚本,解决了设备跨地域部署时的网络自动连接问题,提升了物联网设备的部署效率和稳定性。

fox11的博客 904

严蔚敏《数据结构》——顺序栈

顺序栈,本来想粘代码的,不过学习就是一个比葫芦画瓢的过程,比这代码抄一遍总比cv好,所以我就直接粘图上来了,希望这样能帮助各位理解这每一行代码的意思。 创建的文件为.cpp并不是.c,详见文章末尾。 main交给各位写了,我实现了没有问题的,有问题的请联系我。 学艺不精,若有错误还请多多指教,谢谢。 p.s.在使用Visual Studio编译器的时候输入scanf()方法要用scanf_s() 源码复制请移步公众号 手撕算法。谢谢 所使用编译器为:Visual Stu.

baidu_41119162的博客 416

ubuntu安装英伟达显卡驱动后wifi消失解决方法

ubuntu安装英伟达显卡驱动后(比如4090和3090等),会把wifi和蓝牙驱动去除,导致wifi无法连接。需要重新下载驱动安装。

人工智能(AI)技术,大模型技术,深度学习,机器学习,计算机视觉,AI工具实践应用等分享 3904

java版数据结构题_《数据结构java版》习题解答.doc

《数据结构java版》习题解答.doc I第0章JAVA程序设计基础1【习01】实验01哥德巴赫猜想。1【习02】实验02杨辉三角形。1【习03】实验03金额的中文大写形式。1【习04】实验04下标和相等的数字方阵。1【习05】实验05找出一个二维数组的鞍点2【习06】实验06复数类。2【习07】实验08图形接口与实现图形接口的类2第1章绪论3【习11】实验11判断数组元素是否已按升序排序。3【习...

weixin_35810223的博客 593

cartographer如何使用2个反光柱子作为一个landmark

2个反光柱的摆放要求:靠着墙摆,因为我们只能从一侧看到2个反光柱,从两侧都看到至少需要3个反光柱来定位。 landmark检测原理:因为我们是从一侧看到2个反光柱,所以看到2个反光柱在一帧激光数据中会有顺序,有2种情形,如下图 这两种情形,我们发现 情形1: 这种情形2个反光柱子被检测到的激光角度小于180,我们认为大一些激光角度的是原点。 情形2: 这种情形2个反光柱子被检测到的激光角度大于180,我们认为小一些激光角度的是原点。 这样原点就固定下来,并是唯一的。2个反光柱构成的坐标系也就确定了。和激光坐

南北粉面馆 3827

TensorFlow2深度学习实战(十四):目标检测算法 YOLOv4 解析

最易上手的【计算机视觉】小白教程!

不积跬步,无以至千里! 7636

数据结构c语言作业答案,数据结构C语言版第2版习题答案解析严蔚敏

《数据结构C语言版第2版习题答案解析严蔚敏》由会员分享,可在线阅读,更多相关《数据结构C语言版第2版习题答案解析严蔚敏(77页珍藏版)》请在人人文库网上搜索。1、完美WORD格式 数据结构(C语言版)(第2版)课后习题答案李冬梅 2015.3目 录第1章 绪论1第2章 线性表5第3章 栈和队列13第4章 串、数组和广义表26第5章 树和二叉树33第6章 图43第7章 查找54第8章 排序65专业整...

weixin_39778668的博客 830

统信UOS丨开机无法进入系统 无法打开控制台访问权限,root账号被锁定(cannot open access to console, the root account is locked)

步骤四:分别打开文件发现Roota下的fstab就是我们要找的文件,打开查看Roota的属性发现其为挂载的磁盘nvme0n1p3。步骤三:按Win+E打开文件管理器在分区中查找/etc/fstab文件,发现Roota和Rootb下都有该文件。步骤二:按键盘Ctrl+Alt+F4,进入终端控制台,如下图所示输入startx回车,进入桌面。步骤一:找到UOS系统安装的U盘,选择U盘启动进入安装界面,如下图所示。步骤七:关机,拔出U盘,启动电脑,OK,问题解决。

Reyn_观极 1万+

数据结构c语言版严蔚敏第二版课后答案

数据结构c语言版严蔚敏第二版课后答案 数据结构c语言版第二版课后答案严蔚敏 1.自学编程,难免思路阻塞,收集更新了严蔚敏,吴伟民版《数据结构-C语言版》各章节的课本源码和配套习题集答案解析,目的是为了整理数据结构中的知识点,并与网友交流意见,集思广益,共同进步。这里是所有的源码和课后习题实现目录: 这些源码和答案还有 数据结构 严蔚敏(c语言)第二版PDF书籍 下载地址在文章最下方: 02.本源码...

shemghuodedaan的博客 9899

【深度学习】什么是交叉注意力机制?

输入序列:自注意力机制在同一个输入序列内建立注意力,交叉注意力机制在不同的输入序列间建立注意力。应用场景:自注意力机制多用于单一模态的任务(如纯文本任务),交叉注意力机制多用于多模态任务(如图像和文本的结合)。计算过程:自注意力机制的查询、键和值都来自同一个输入序列,而交叉注意力机制的查询来自一个输入序列,键和值来自另一个输入序列。

q742971636的博客 7372

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【亲测免费】 02331数据结构教材扫描版

02331数据结构教材扫描版 去发现同类优质开源项目:https://gitcode.com/ 此仓库提供了自考02331数据结构教材的扫描版,内容全面系统,覆盖数据结构的核心知识点。以下是资源文件的具体内容介绍: 线性表:详细讲解线性表的定义、操作及其应用。 栈和队列:深入介绍栈和队列的原理及实际应用场景。 串:涉及串的基本操作和高级处理技术。 多维数组和广义表:多维数组和广义表的表示方法及应...

gitblog_06743的博客 379

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

《剑指 Offer (第 2 版)》栈部分 JavaScript 题解

《剑指 Offer (第 2 版)》栈部分 JavaScript 题解《剑指 Offer (第 2 版)》栈部分 JavaScript 题解06. 从尾到头打印链表09. 用两个栈实现队列30. 包含min函数的栈31. 栈的压入、弹出序列33. 二叉搜索树的后序遍历序列36. 二叉搜索树与双向链表 《剑指 Offer (第 2 版)》栈部分 JavaScript 题解 《剑指 Offer(第 2 版)》通行全球的程序员经典面试秘籍。剖析典型的编程面试题,系统整理基础知识、代码质量、解题思路、优化效率和综合

p1967914901的博客 352

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

数据结构教程第6版上机实验指导-源程序:实践与理解的完美结合

数据结构教程第6版上机实验指导-源程序:实践与理解的完美结合 【下载地址】数据结构教程第6版上机实验指导-源程序 《数据结构教程(第6版)》上机实验源程序合集,为学习者提供实践操作的代码模板,帮助深入理解数据结构的核心概念与实际应用。文件包含各章节对应的实验源代码,便于跟随教程逐步实践,巩固知识点。通过动手编程,读者能够...

gitblog_06722的博客 456

c语言课后作业答案第二版,数据结构c语言版第2版课后习题答案.doc

数据结构c语言版第2版课后习题答案.doc 数据结构(C语言版)(第2版)课后习题答案李冬梅2015.3I目录第1章绪论1第2章线性表5第3章栈和队列13第4章串、数组和广义表26第5章树和二叉树33第6章图43第7章查找54第8章排序650第1章绪论1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。答案:数据:是客观事物的符号表示,指所有能输入到计算...

weixin_39622150的博客 531

数据结构 栈,队列,串

这篇文章是关于严蔚敏清华版《数据结构》教材的代码,包括书上大纲规定的线性表,链表,栈,队列,二叉树,图,排序, 查找等基本算法的编码,还包括循环链表,广义表,两栈共享空间,字符串模式匹配等非常规,较难数据结构的编码,除此之外书本 后面大量的思考题,例如约瑟夫环,括号匹配,迷宫问题,八皇后,火车厢重排,斐波那契查找等一些列经典问题也有代码。文章中 的代码,均已调试通过,并附有程序运行结果,读者...

weixin_30906425的博客 98

【数据结构】栈是什么?从0理解栈的数据结构

在数据结构的学习中,栈是一种非常重要的结构。无论你是否是计算机专业,栈的概念其实并不复杂。本篇文章将帮助你从零理解栈的数据结构,了解它的基本用途、实际应用以及如何在C++中实现栈操作。

XuanRan的博客 4544
上一篇: 新的开始(北京版)
下一篇: 线性表题解
小陈又菜
博客等级 码龄3年 680粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值