当前位置: 首页 > news >正文

数据结构之栈的讲解(源代码+图解+习题)

        我们在学习过顺序表和链表之后,了解了使用数组存储数据,使用结构体来存储数据和有关的指针,这些都是底层的东西,链表是靠指针的链接,顺序表是靠数组的下标才能得以实现增删查改。众多数据结构其实底层都离不开数组,指针和结构体,今天我们要学习的栈也不例外,话不多说,直接上正菜!

1. 栈的概念:

        在这里我先给大家栈的图解,通过图来理解概念。

1.1 栈的组成

        栈:黑色边框及其内部空间为栈

        栈顶:开口的方向叫做栈顶

        栈底:闭口的方向叫做栈底

        栈内元素:蓝色长方形

1.2 栈的进出规则(先进后出)

        首先,我们往栈里存入或者删除数据的时候,只能在栈顶操作,也就是咱们俗话说的,从栈顶这一头进行增删的操作,那么我们入栈的顺序是1-2-3-4的时候,出栈的顺序就是4-3-2-1了。

        我们不可以在栈底或者中间直接拿出来数据,只能在栈顶拿,谁在栈顶先拿谁,肯定是最后入栈的数据在栈顶。

        所以栈的进出规则是 先进后出

        

2. 栈的底层架构的选择

        我们知道,栈的进出规则是先进后出,我们秉持着这一理念就可以在顺序表或者链表中进行改造增删查改的规则,使其变成栈。那我们该如何选择呢?是选择顺序表还是链表呢?

2.1 栈的架构为顺序表(文末有源码,是使用方案)

2.1.1 栈和顺序表的比对

        首先我们看一下用顺序表来构造栈是如何构造的。

        当我们的栈是顺序表构造的时候,我们会发现栈底就是顺序表的表头,栈顶是顺序表的表尾。那通过顺序表如何对栈进行插入数据和删除数据呢?

2.1.2 栈的插入图解

        我们对栈的插入,一定是在栈顶这边插入,那我们对比一下这两张图,在栈顶插入就相当于顺序表的尾插对吧!我们只需要尾插顺序表就可以完成栈的插入元素了。

2.1.3 栈的删除

        栈是只能对栈顶进行增加和删除的,所以我们只能在栈顶删除元素,那是不是就相当于顺序表的尾删。

        所以对于栈的删除,我们只需要尾删顺序表就可以了。

2.2 栈的架构为链表

        而当我们使用链表作为栈的架构,什么样的链表才可以使栈的增添和删除容易呢?让我们看图一起寻找吧!

2.2.1 单链表构造栈(舍弃方案)

        当我们使用单链表构造栈的时候,栈的插入和删除都相当于对单链表的尾部进行操作,插入还好,直接尾插就行,而删除的话,删除当前节点就找不到前一个节点了,我们还需要保存前一个节点,这样很麻烦,所以这个方案是舍弃的。

2.2.2 双向链表构造栈(舍弃方案)

        对于双向链表很明显是比单链表好用,在出栈的操作,我们应该先保存栈顶元素的下一个元素的位置,也就是我们要删除图中的3,应该先保存2的位置,如果我们不保存2的位置,直接删除3,那么就找不到2的位置了。所以保存2的位置之后,删除3,再将指向3的指针 重新指向2就可以了。这个方法很明显比单链表好用,但是都没有顺序表构造的栈更方便直接,大家可以下去尝试使用双向链表模拟实现栈。

        

        最后下面我们来用代码模拟一下栈,这里首推顺序表。

3. 栈的模拟实现(源代码)

3.1 栈的定义

typedef int STDataType; 
//用顺序表模拟栈
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;

3.2 栈的初始化

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

3.3 栈的销毁

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

3.4 入栈

void STPush(ST* ps, STDataType x)
{assert(ps);// 11:40if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}

3.5 取栈顶元素

STDataType STTop(ST* ps)
{assert(ps);// assert(ps->top > 0);return ps->a[ps->top - 1];
}

3.6 出栈

void STPop(ST* ps)
{assert(ps);// assert(ps->top > 0);--ps->top;
}

3.7 栈的元素个数

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

3.8 栈是否为空

bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}

3.9 用到的头文件

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

        以上就是栈的模拟实现了,下面我们做几个关于栈的习题。

4. 栈的习题

4.1 下列关于栈的叙述正确的是( )

        A.栈是一种“先进先出”的数据结构

        B.栈可以使用链表或顺序表来实现

        C.栈只能在栈底插入数据

        D.栈不能删除数据

答案:B

A错误:栈是一种先进后出的数据结构,队列是先进先出的。

B正确:顺序表和链表都可以用来实现栈,不过一般都使用顺序表,因为顺序表简单。

C错误:栈只能在栈顶进行输入的插入和删除操作。

D错误:栈是有入栈和出栈的操作,出栈就是从栈中删除一个元素。

4.2 一个栈的入栈序列为ABCDE,则不可能的出栈序列为( )

        A.ABCDE

        B.EDCBA

        C.DCEBA

        D.ECDBA

答案:D 

画图解决问题

4.3. 链栈与顺序栈相比,比较明显的优点是( )

        A.插入操作更加方便

        B.删除操作更加方便

        C.入栈时不需要扩容

答案:C

A错误,如果是链栈,在入栈的时候,直接尾插就行了,跟顺序栈没有多大区别。

B错误,如果是链栈,在出栈的时候,需要继续前一个节点的位置才行,要不然无法继续出栈,               而顺序栈则可以通过下标快速找到。链表的操作比顺序表复杂,因此使用顺序结构实现栈更简单。

C正确:链式结构实现栈时,每次入栈相当于链表中头插一个节点,没有扩容一说。

以上就是本次博文的分享,谢谢大家支持!

相关文章:

数据结构之栈的讲解(源代码+图解+习题)

我们在学习过顺序表和链表之后&#xff0c;了解了使用数组存储数据&#xff0c;使用结构体来存储数据和有关的指针&#xff0c;这些都是底层的东西&#xff0c;链表是靠指针的链接&#xff0c;顺序表是靠数组的下标才能得以实现增删查改。众多数据结构其实底层都离不开数组&…...

内网渗透-内网信息收集

内网信息收集 前言 当我们进行外网信息收集&#xff0c;漏洞探测以及漏洞利用后&#xff0c;获得了主机的权限后&#xff0c;我们需要扩大渗透的战果时&#xff0c;这是我们就要进行内网的渗透了&#xff0c;内网渗透最重要的还是前期的信息收集的操作了&#xff0c;就是我们的…...

​LeetCode解法汇总2520. 统计能整除数字的位数

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 描述&#xff1a; 给你一个整…...

Lua语言编写爬虫程序

以下是一个使用luasocket-http库和Lua语言编写的爬虫程序。此程序使用了https://www.duoip.cn/get_proxy的代码。 -- 引入所需的库 local http require("socket.http") local ltn12 require("ltn12") local json require("json") ​ -- 获取…...

安防监控项目---概要

文章目录 前言一、项目需求二、环境介绍三、关键点四、主框架分析总结 前言 各位小伙伴&#xff0c;在蛰伏了将近有半年的时间又要和大家分享新的知识了&#xff0c;这次和大家分享的是一个项目&#xff0c;因此呢我准备分项目阶段去和大家分享&#xff0c;希望大家都能够在每…...

数仓经典面试题

1.什么是数据仓库&#xff1f;请谈谈你对数据仓库的理解。 数据仓库是一个用于存储和管理数据的系统&#xff0c;它可以将分散的、异构的数据源中的数据进行抽取、转换、清洗和整合&#xff0c;然后按照一定的模型和架构进行组织和存储&#xff0c;以便更好地支持决策分析和业…...

【ARM Coresight 系列文章 15.2 – components power domain 详细介绍】

文章目录 1.1. Coresight 电源域模型1.1.1 CDBGPWRUPREQ 和 CDBGPWRUPACK1.1.2 CSYSPWRUPREQ 和 CSYSPWRUPACK1.1.3 Power Domain ID In RomTable1.1.4 Power domain entries1.1.5 Algorithm to discover power domain IDs1.1.6 Debug power requests1.1.7 System power reques…...

Flutter Android IOS 获取通讯录联系人列表

1.在pubspec.yaml 文件中添加 contacts_service 和 permission_handler 插件的依赖&#xff1a; dependencies:contacts_service: ^0.6.3 #获取联系人permission_handler: ^11.0.1 #权限请求2.在你的 Dart 代码中&#xff0c;导入 contacts_service 插件&#xff1a; impo…...

Spring Boot集成SpringFox 3.0与Pageable参数处理

Springfox 3.0有多个模块&#xff0c;提供了spring boot starter&#xff0c;与Spring Boot集成时仅需引入springfox-boot-starter&#xff0c;如下&#xff1a; <dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter<…...

2、基于pytorch lightning的fabric实现pytorch的多GPU训练和混合精度功能

文章目录 承接 上一篇,使用原始的pytorch来实现多GPU训练和混合精度&#xff0c;现在对比以上代码&#xff0c;我们使用Fabric来实现相同的功能。关于Fabric&#xff0c;我会在后续的博客中继续讲解&#xff0c;是讲解&#xff0c;也是在学习。通过fabric,可以减少代码量&#…...

python版opencv人脸训练与人脸识别

1.人脸识别准备 使用的两个opencv包 D:\python2023>pip list |findstr opencv opencv-contrib-python 4.8.1.78 opencv-python 4.8.1.78数据集使用前一篇Javacv的数据集,网上随便找的60张图片,只是都挪到了D:\face目录下方便遍历 D:\face\1 30张刘德华图片…...

计算机视觉-数学基础*变换域表示

被研究最多的图像&#xff08;或任何序列数据&#xff09;变换域表示是通过傅 里叶分析 。所谓的傅里叶表示就是使用 正弦函数的线性组合来表示信号。对于一个给定的图像I(n1,n2) &#xff0c;可以用如下方式分解它&#xff08;即逆傅里叶变换&#xff09;&#xff1a; 其中&a…...

小程序如何设置自取规则

​在小程序中&#xff0c;自取规则是指当客户下单时选择无需配送的情况下&#xff0c;如何设置相关的计费方式、指定时段费用、免费金额、预定时间和起取金额。下面将详细介绍如何设置这些规则&#xff0c;以便更好地满足客户的需求。 在小程序管理员后台->配送设置->自…...

Elasticsearch分词器-中文分词器ik

文章目录 使用standard analysis对英文进行分词使用standard analysis对中文进行分词安装插件对中文进行友好分词-ik中文分词器下载安装和配置IK分词器使用ik_smart分词器使用ik_max_word分词器 借助Nginx实现ik分词器自定义分词网络新词 ES官方文档Text Analysis 使用standard…...

ITSS信息技术服务运行维护标准符合性证书申请详解及流程

ITSS信息技术服务运行维护标准符合性证书 认证介绍 ITSS&#xff08;InformationTechnologyServiceStandards,信息技术服务标准&#xff0c;简称ITSS)是一套成体系和综合配套的信息技术服务标准库&#xff0c;全面规范了IT服务产品及其组成要素&#xff0c;用于指导实施标准化…...

Inbound marketing的完美闭环:将官网作为营销枢纽,从集客进化为入站

Inbound marketing即入站营销的运作方式不同于付费广告&#xff0c;你需要不断地投入才能获得持续的访问量。而你的生意表达内容一经创建、发布&#xff0c;就能远远不断地带来流量。 Inbound marketing也被翻译作集客营销&#xff0c;也就是美国知名的营销SaaS企业hubspot所主…...

SQL On Pandas最佳实践

SQL On Pandas最佳实践 1、PandaSQL1.1、PandaSQL简介1.2、Pandas与PandaSQL解决方案对比1.3、PandaSQL支持的窗口函数1.4、PandaSQL综合使用案例2、DuckDB2.1、DuckDB简介2.2、SQL操作(SQL On Pandas)2.3、逻辑SQL(DSL on Pandas)2.4、DuckDB on Apache Arrow2.5、DuckDB …...

如何批量给视频添加logo水印?

如果你想为自己的视频添加图片水印&#xff0c;以增强视频的辨识度和个性化&#xff0c;那么你可以使用固乔剪辑助手软件来实现这一需求。下面就是详细的操作步骤&#xff1a; 1.下载并打开固乔剪辑助手软件&#xff0c;这是一款简单易用的视频剪辑软件&#xff0c;功能丰富&am…...

数据挖掘和大数据的区别

数据挖掘 一般用于对企业内部系统的数据库进行筛选、整合和分析。 操作对象是数据仓库&#xff0c;数据相对有规律&#xff0c;数据量较少。 大数据 一般指对互联网中杂乱无章的数据进行筛选、整合和分析。 操作对象一般是互联网的数据&#xff0c;数据无规律&#xff0c;…...

Go之流程控制大全: 细节、示例与最佳实践

引言 在计算机编程中&#xff0c;流程控制是核心的组成部分&#xff0c;它决定了程序应该如何根据给定的情况执行或决策。以下是Go语言所支持的流程控制结构的简要概览&#xff1a; 流程控制类型代码if-else条件分支if condition { } else { }for循环for initialization; con…...

FLStudio2024最新破解版注册机

水果音乐制作软件FLStudio是一款功能强大的音乐创作软件,全名:Fruity Loops Studio。水果音乐制作软件FLStudio内含教程、软件、素材,是一个完整的软件音乐制作环境或数字音频工作站... FL Studio21简称FL 21&#xff0c;全称 Fruity Loops Studio 21&#xff0c;因此国人习惯叫…...

【Overload游戏引擎细节分析】standard材质Shader

提示&#xff1a;Shader属于GPU编程&#xff0c;难写难调试&#xff0c;阅读本文需有一定的OpenGL基础&#xff0c;可以写简单的Shader&#xff0c;不适合不会OpenGL的朋友 一、Blinn-Phong光照模型 Blinn-Phong光照模型&#xff0c;又称为Blinn-phong反射模型&#xff08;Bli…...

Leetcode—7.整数反转【中等】

2023每日刷题&#xff08;十&#xff09; Leetcode—7.整数反转 关于为什么要设long变量 参考自这篇博客 long可以表示-2147483648而且只占4个字节&#xff0c;所以能满足题目要求 复杂逻辑版实现代码 int reverse(int x){int arr[32] {0};long y;int flag 1;if(x <…...

lua-web-utils和proxy设置示例

以下是一个使用lua-web-utils和proxy的下载器程序&#xff1a; -- 首先安装lua-web-utils库 local lwu require "lwu" ​ -- 获取服务器 local function get_proxy()local proxy_url "duoipget_proxy"local resp, code, headers, err lwu.fetch(proxy_…...

分享一下在微信小程序里怎么添加储值卡功能

在微信小程序中添加储值卡功能&#xff0c;可以让消费者更加便捷地管理和使用储值卡&#xff0c;同时也能增加商家的销售收入。下面是一篇关于如何在微信小程序中添加储值卡功能的软文。 标题&#xff1a;微信小程序添加储值卡功能&#xff0c;便捷与高效并存 随着科技的不断发…...

2023高频前端面试题-http

1. HTTP有哪些⽅法&#xff1f; HTTP 1.0 标准中&#xff0c;定义了3种请求⽅法&#xff1a;GET、POST、HEAD HTTP 1.1 标准中&#xff0c;新增了请求⽅法&#xff1a;PUT、PATCH、DELETE、OPTIONS、TRACE、CONNECT 2. 各个HTTP方法的具体作用是什么&#xff1f; 方法功能G…...

图像识别在自动驾驶汽车中的多传感器融合技术

摘要&#xff1a; 介绍文章的主要观点和发现。 引言&#xff1a; 自动驾驶汽车的兴起和重要性。多传感器融合技术在自动驾驶中的关键作用。 第一部分&#xff1a;图像识别技术 图像识别的基本原理。图像传感器和摄像头在自动驾驶中的应用。深度学习和卷积神经网络&#xff…...

Kafka To HBase To Hive

目录 1.在HBase中创建表 2.写入API 2.1普通模式写入hbase&#xff08;逐条写入&#xff09; 2.2普通模式写入hbase&#xff08;buffer写入&#xff09; 2.3设计模式写入hbase&#xff08;buffer写入&#xff09; 3.HBase表映射至Hive中 1.在HBase中创建表 hbase(main):00…...

python pandas.DataFrame 直接写入Clickhouse

import pandas as pd import sqlalchemy from clickhouse_sqlalchemy import Table, engines from sqlalchemy import create_engine, MetaData, Column import urllib.parsehost 1.1.1.1 user default password default db test port 8123 # http连接端口 engine create…...

德语中第二虚拟式在主动态的形式,柯桥哪里可以学德语

德语中第二虚拟式在主动态的形式 1. 对于大多数的动词&#xff0c;一般使用这样的一般现在时时态&#xff1a; wrde 动词原形 例句&#xff1a;Wenn es nicht so viel kosten wrde, wrde ich mir ein Haus am Meer kaufen. 如果不花这么多钱&#xff0c;我会在海边买一栋房…...