第五章 栈的讲解与实现

news2024/11/25 20:46:49

初阶数据结构

第一章 时间复杂度和空间复杂度
第二章 动态顺序表的实现
第三章 单向链表的讲解与实现
第四章 带头双向链表的讲解与实现
第五章 栈的讲解与实现


文章目录

  • 初阶数据结构
  • 前言
  • 一、栈
    • 1、什么是栈?
  • 二、栈的定义
  • 三、接口函数的实现
    • 1、初始化
    • 2、判断是否为空
    • 3、插入
    • 4、删除
    • 5、元素个数
    • 6、读取栈顶元素
    • 7、销毁
  • 四、栈中元素的访问


前言

前面的章节中,我们介绍了线性表中的动态顺序表、单向链表以及带头双向链表的实现,今天我们讲解另外一种数据结构——栈。


一、栈

1、什么是栈?

栈的逻辑结构如下所示:类似于一个桶,然后我们从栈顶的位置往里放数据。
在这里插入图片描述
那么这个数据结构有什么特点呢?
我们从图中可以看出,我们想要取出标号为1的元素时,需要先按照4、3、2的顺序依次取出1上端的数据。因此我们便能发现,第一个放进去的数据是最后出来的,最后一个放进去的数据是第一个出来的。
那么我们将这种特点称之为:先进后出
在这里插入图片描述

二、栈的定义

我们在理解了栈的逻辑结构后,我们应该如何实现呢?在回答这个问题之前,我们先将这种逻辑结构换一种表示方式:
在这里插入图片描述
看到这种表示方式后,我们最容易想到的,用来实现栈的方式就是数组。那么我们上次用数组实现的数据结构是顺序表。既然顺序表可以用来实现栈,那么链表可以吗?
其实也是可以的,如下图所示:
在这里插入图片描述

那么这两种方式哪一种更优呢?
我们发现栈这种数据结构是不存在随即插入这种方式的,因为它只能尾插。因此,顺序表的弊病之一就得以躲避了。但是我们以链表的方式来模拟的时候,我们需要不断地找尾,这个过程的时间复杂度是O(N)。或许我们可以通过事先创建一个尾指针来规避查找尾部节点的过程,但在变量的创建上,链表也会额外创建指针变量来存储地址。因此,在栈的实现上,以数组的形式来实现是比较好的。

基于上述的描述,我们就能定义一个栈了

typedef int ElementType;
typedef struct Stack
{
	ElementType* a;//指向动态数组的指针
	int top;//栈顶元素的下一个位置的下标
	int capacity;//动态数组的容量
}ST;

三、接口函数的实现

1、初始化

void StackInit(ST*ps)
{
	assert(ps!=NULL);
	ps->a=NULL;
	ps->top=ps->capacity=0;
}

将指针设置为空,将top和capacity设置为0。

2、判断是否为空

int StackEmpty(ST*ps)
{
	if(ps->top==0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

当一个栈为空的时候,恰好就是top为0的时候,因此,我们可以通过top来判断栈是否为空。
在这里插入图片描述

3、插入

栈种的数据插入均采用的是尾插,即在数组的末尾插入。但是在插入之前,我们需要判断一下容量的大小。当容量不足的时候,我们需要适当地进行扩容。这项操作和我们在实现顺序表的时候,所执行的操作是一样的。

void StackPush(ST* ps, ElementType dat)
{
	assert(ps!=NULL);
	if (ps->top == ps->capacity)
	{
		int newcapacity = (ps->capacity == 0) ? 4 : ps->capacity * 2;
		ElementType* temp = realloc(ps->a,sizeof(ST)*newcapacity);
		if (temp == NULL)
		{
			printf("Failed to realloc!\n");
			exit(-1);
		}
		ps->a = temp;
		ps->capacity = newcapacity;
	}

	ps->a[ps->top] = dat;//top是原数组中最后一个元素的下一个位置
	ps->top++;
}

在这里插入图片描述

4、删除

因为栈这种数据结构所具备的特点是元素满足先进后出,后进先出。那么何为进?即向栈种插入数据,那么何为出?即从栈中删除的数据。而每次删除的数据都是栈中最后插入的那个数据。即尾删
但是在删除的时候我们有两点注意事项:
1、空的栈不用删除
2、top不能为负数,否则在插入数据的时候会违法访问。

上述两点的关键就是判断我们的栈是否为空。

void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	ps->top--;
}

5、元素个数

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

top就相当于顺序表中的size,所以我们直接放回top的数值即可。

6、读取栈顶元素

ElementType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	return ps->a[ps->top-1];
}

在这里插入图片描述

7、销毁

void StackDestory(ST*ps)
{
	assert(ps!=NULL);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->a = 0;
}

直接释放即可。

四、栈中元素的访问

栈是无法像顺序表和链表那样不断地遍历元素的。因为,想要遍历元素必须取出栈顶元素,也就是说,我们必须删除栈顶的元素才能访问到下一个元素。因此,栈只能遍历一次,遍历一次之后就代表着栈已经空了。
除此以外,元素的访问顺序和插入顺序是相反的。
比如我们是按照1,2,3,4的顺序插入,那么访问的顺序就是4,3,2,1。
那么我们如何访问呢?如下图所示:

ST stack;//定义一个栈
StackInit(&stack);//初始化一个栈
//向栈中插入数据
StackPush(&stack,1);
StackPush(&stack,2);
StackPush(&stack,3);
StackPush(&stack,4);
StackPush(&stack,5);
//通过访问栈顶、删除栈顶的循环方式访问栈中的每一个元素。
while(!StackEmpty(&stack))
{
	printf("%d ",StackTop(&stack));
	StackPop(&stack);
}
StackDestory(&stack);//销毁栈

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

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

相关文章

前端js手写面试题看这篇就够了

实现一个JSON.stringify JSON.stringify(value[, replacer [, space]]):Boolean | Number| String类型会自动转换成对应的原始值。undefined、任意函数以及symbol,会被忽略(出现在非数组对象的属性值中时),或者被转换…

利用opencv 做一个疲劳检测系统(2)

文章目录杂谈实现步骤核心算法交互界面界面代码检测效果源代码杂谈 最近发现视力下降严重, 可能跟我的过度用眼有关,于是想着能不能做一个检测用眼疲劳的,灵感来自特斯拉的疲劳检测系统。 效果如下: 实现步骤 实现核心算法制作…

【消息队列笔记】chp2-如何选择消息队列

一、选择消息队列的基本标准 不同的消息队列产品在功能和特性方面是各有优劣的,但是我们在选择的时候应尽量保证一个通用的最低标准。 1.必须是开源的产品 开源很重要,如果在使用该产品时遇到了影响业务的bug,可以通过修改源代码来进行修复…

音视频开发基础概念

目录一、音视频如何采集和表示1、音视频录制原理2、音视频播放原理二、视频基础概念1、图像基础概念2、RGB、 YUV深入讲解3、RGB和YUV的转换4、YUV Stride对齐问题三、视频为什么要做编码四、音频基础概念1、基本概念2、声音的物理性质-频率-音频采样率3、数字声音的表示4、音频…

【数据结构】——顺序表

目录 1.线性表 2.顺序表 2.1概念及结构 3.静态顺序表 4.动态顺序表 1.定义一个顺序表 2.顺序表的初始化和销毁 3.顺序表尾插 4.顺序表打印 5.顺序表尾删 6.顺序表头插 7.顺序表头删 8.在pos(任意)位置的插入 9.在pos(任意&#…

[附源码]计算机毕业设计JAVAjsp美容院业务管理系统

[附源码]计算机毕业设计JAVAjsp美容院业务管理系统 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM m…

用DIV+CSS技术设计的体育篮球主题 校园体育网页与实现制作(web前端网页制作课作业)

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

SpringBoot(二):基础配置文件、yaml语法、多环境开发配置

目录 一、配置文件 1、配置文件格式 2、自动提示功能失灵解决方案 3、SpringBoot配置文件加载顺序 二、yaml 1、yaml介绍 2、yaml语法规则 3、yaml数组数据 4、yaml数据读取 三、多环境开发配置 1、多环境启动配置 2、多环境启动命令格式 3、多环境开发控制 四、…

VS Code常用操作

文章目录常用快捷键修改VS Code底部状态栏颜色VS Code添加Anaconda的Python源常用快捷键 (1) 对于 行 的操作: 重开一行:光标在行尾的话,回车即可;      不在行尾,Ctrl Enter 向下重开一行;    …

手拉手一起学HTML(下)——表格标签和列表标签,表单标签

🍓个人主页:bit.. 🍒系列专栏:Linux(Ubuntu)入门必看 C语言刷题 数据结构与算法 目录 一.表格标签 1.1表格的主要作用 1.2表格的基本语法 1.3表头单元格标签 1.4表格属性 1.5表格结构标签 1.6合并单元格&#xff08…

prometheus 监控

【00】结构原理微服务中的监控分根据作用领域分为三大类,Logging,Tracing,Metrics。* Logging - 用于记录离散的事件。例如,应用程序的调试信息或错误信息。它是我们诊断问题的依据。比如我们说的ELK就是基于Logging。* Metrics -…

HTTP协议详解

1.HTTP协议介绍 先来给大家介绍以下HTTP: HTTP(Hyper Text Transfer Protocol): 全称超文本传输协议,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。HTTP 是一种…

【网络篇】如何搭建自己的DNS服务器

引言 平时练习域名解析,一般直接修改的/etc/hosts文件。对于服务器数量小的情况完全可以,但是如果服务器数量较多,每个都修改比较麻烦。 DNS是作为域名解析。在实际的生产过程中,尤其是对于内网搭建的情况,DNS不可能…

宝塔面板如何设置301重定向,为什么网站要设置重定向?

大家好,我是Q站小编鹏仔,本次给大家带来的教程是宝塔面板如何设置301重定向。 在设置之前,我们需先明白为什么要设置重定向呢? 在购买域名时,域名本身是不带有www的,由于在以前网站方都会增加一个"ww…

C#项目实战|人脸识别考勤

此文主要通过WinForm来制作的一个人脸识别考勤打卡程序,有兴趣的小伙伴可以接入到打卡机上。 一、实现流程1.1、创建项目1.2、设计页面1.3、创建应用1.4、获取Token及参数解析1.5、与人脸数据比对并展示一、实现流程 1.1、创建项目 打开Visual Studio,右…

HTML+CSS静态网页设计:(房地产网站设计与实现6页)

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

javascript事件处理二 事件对象event详解及target和currentTarget区别

在处理事件的时候,所有和事件相关的东西都封装到event这个对象里面。所以这个对象非常的重要。这个对象有非常多的内容,我们讨论几个计较常见和以及比较难区别的target和currentTarget。 常见属性 页面就是一个div,然后我们监听他的oclick事…

Python+大数据-Spark技术栈(三) SparkCore加强

Python大数据-Spark技术栈(三) SparkCore加强 重点:RDD的持久化和Checkpoint提高拓展知识:Spark内核调度全流程,Spark的Shuffle练习:热力图统计及电商基础指标统计combineByKey作为面试部分重点,可以作为扩展知识点 …

NLP | XLNet :用于语言理解的广义自回归预训练 论文详解

论文:XLNet: Generalized Autoregressive Pretraining for Language Understanding 论文地址:https://proceedings.neurips.cc/paper/2019/file/dc6a7e655d7e5840e66733e9ee67cc69-Paper.pdf 1.介绍 XLNet 是从蓬勃发展的自然语言处理 (NLP) 领域中出…

食用前须知(阅读并同意后在食用其他部分)

昨天刚和计科某数据结构老师聊这个事 让我别写题解了 以后会偷摸的在csdn更,大家千万低调点,严谨点!!! 一般不会当天更了,会拖个一两天,大家先把会的写写,不会的再来看我教程 就算真…