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

数据结构(三)——栈

三、栈、队列和数组

3.1 栈

3.1.1 栈的基本概念

线性表是具有相同数据类型的n(n≥0)个数据元素的有限 序列,其中n为表长,当n = 0时线 性表是一个空表。若用L命名线性表,则其一般表示为 L = (a1, a2, … , ai , ai+1, … , an)

栈(Stack)是只允许在一端进行插入或删除操作的线性表
逻辑结构:与普通线性表相同 数据的运算:插入、删除操作有区别

重要术语:栈顶、栈底、空栈
栈顶:允许插入 和删除的一端 (最后进的即最上面的为栈顶元素)
栈底:不允许插 入和删除的一端(最先进的即最下面的为栈底元素)
空栈:不含任何元素的栈

特点:后进先出(后进栈的元素先出栈)  记为LIFO (Last In First Out)

栈的基本操作

  • InitStack(&S):初始化栈。构造一个空栈 S,分配内存空间。
  • DestroyStack(&S):销毁栈。销毁并释放栈 S 所占用的内存空间。
  • Push(&S,x):进栈,若栈S未满,则将x加入使之成为新栈顶。
  • Pop(&S,&x):出栈,若栈S非空,则弹出栈顶元素,并用x返回。
  • GetTop(S, &x):读栈顶元素。若栈 S 非空,则用 x 返回栈顶元素

其他常用操作

  • StackEmpty(S):判断一个栈 S 是否为空。若S为空,则返回true,否则返回false

栈的常考题型
进栈顺序为: a à b à c à d à e  有哪些合法的出栈顺序?

3.1.2 栈的顺序存储实现

顺序栈的定义:

#define MaxSize 10         //定义栈中元素的最大个数
typedef struct{    ElemType data[MaxSize];       //静态数组存放栈中元素    int top;                      //栈顶指针 用于指向此时栈中的栈顶元素 一般用来记录数组的下标
}SqStack;void testStack(){    SqStack S;       //声明一个顺序栈(分配空间)
}

顺序存储:给各个数据元素分配连续的存储空间,大小为MaxSize*sizeof(ElemType) 

初始化操作

#define MaxSize 10                 //定义栈中元素的最大个数
typedef struct{   ElemType data[MaxSize];        //静态数组存放栈中元素int top;                       //栈顶指针
}SqStack;// 初始化栈
void InitStack(SqStack &S){ S.top = -1;                   //初始化栈顶指针
}void testStack(){SqStack S;                    //声明一个顺序栈(分配空间)InitStack(S);//...后续操作...
}// 判断栈是否为空
bool StackEmpty(SqStack S){    if(S.top == -1)                //栈空return true;    else                           //不空return false;
}

进栈操作

#define MaxSize 10                    //定义栈中元素的最大个数
typedef struct{ElemType data[MaxSize];           //静态数组存放栈中元素int top;                          //栈顶指针
}SqStack;    // 新元素进栈
bool Push(SqStack &S, ElemType x){    // 判断栈是否已满   满了报错  if(S.top == MaxSize - 1)        return false;    S.top = S.top+1;                  //指针先加1S.data[S.top]=x;                  //新元素入栈 把x存到top指针所在的位置return true;
}S.top = S.top+1;                  //指针先加1S.data[S.top]=x;                  //新元素入栈 把x存到top指针所在的位置上面两句代码等价于S.data[++S.top]=x;                //++top表示,先让top的值加1 再来使用top

 出栈操作

#define MaxSize 10                    //定义栈中元素的最大个数
typedef struct{ElemType data[MaxSize];           //静态数组存放栈中元素int top;                          //栈顶指针
}SqStack;    // 出栈
bool Pop(SqStack &x, ElemType &x){    // 判断栈是否为空    if(S.top == -1)                   //栈空报错return false;    x = S.data[S.top--];    return true;
}x = S.data[S.top--];    等价于x=S.data[S.top];                     //栈顶元素先出栈S.top=S.top-1;                       //指针再减1top指针减1 数据还残留在内存中,指示逻辑上被删除了

栈顶指针:S.top,初始化时设置S.top=-1;栈顶元素:S.data[S.top]
进栈操作:栈不满时,栈顶指针先加1,再送值到栈顶
出栈操作:栈非空时,先取栈顶元素,再将栈顶指针减1
栈空条件:S.top==-1,栈满条件:S.top==MaxSize-1;栈长:S.top+1

读取栈顶元素

// 读栈顶元素 
bool GetTop(SqStack S, ElemType &x){        if(S.top == -1)               //栈空 报错   return false;        x = S.data[S.top];            //x记录栈顶元素 和出栈操作基本一样,唯一区别是这里top不需要-- return true; 
}

 仅为读取栈顶元素,并没有出栈操作,因此原栈顶元素依然保留在栈中
共享栈(利用栈底位置相对不变的特性,让两个顺序栈共享一个一维数组空间):
将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸

#define MaxSize 10                //定义栈中元素的最大个数
typedef struct{       ElemType data[MaxSize];       //静态数组存放栈中元素  int top0;                     //0号栈栈顶指针  int top1;                     //1号栈栈顶指针
}ShStack;// 初始化栈
void InitSqStack(ShStack &S){    S.top0 = -1;                  //初始化栈顶指针S.top1 = MaxSize;   
}/*仅当两个栈顶指针相邻(top1-top0=1)时,判断为栈满
0号栈进栈时top0先加1再赋值
1号栈进栈时top1先减1再赋值
出栈时则相反*/

栈满的条件:top0 + 1 == top1

共享栈是为了更有效地利用存储空间,两个栈的空间相互调剂,只有在整个存储空间被占满时才发生上溢,其存取数据的时间复杂度为O(1),所以对存取效率没有什么影响

3.1.3 栈的链式存储实现

采用链式存储的栈称为链栈,链栈的优点是便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况,通常采用单链表实现,并规定所有操作都是在单链表的表头进行的


链栈的定义 和单链表的定义几乎没差别

typedef struct Linknode{        ElemType data;        //数据域    Linknode *next;       //指针域
}*LiStack;void testStack(){   LiStack L;            //声明一个链栈
}

采用链式存储,便于结点的插入与删除。链栈的操作与链表类似,入栈和出栈的操作都在链的表头进行。需要注意的是,对于带头结点和不带头结点的链栈,具体的实现会有所不同。

链栈的初始化

typedef struct Linknode{       ElemType data;      Linknode *next;
}*LiStack;// 初始化栈
bool InitStack(LiStack &L){    L = (Linknode *)malloc(sizeof(Linknode));   if(L == NULL)             return false;   L->next = NULL;    return true;
}// 判断栈是否为空
bool isEmpty(LiStack &L){    if(L->next == NULL)      return true;   else           return false;
}

入栈出栈

// 新元素入栈
bool pushStack(LiStack &L,ElemType e){  Linknode *s = (Linknode *)malloc(sizeof(Linknode));  if(s == NULL)               //内存分配失败 return false;   s->data = e;                //用结点s保存数据元素es->next = L->next;          //头插法      L->next = s;                //把s结点连到L后return true;
}// 出栈
bool popStack(LiStack &L, int &e){     if(L->next == NULL)         // 栈空不能出栈  return false;    Linknode *s = L->next;  x = s->data;       L->next = s->next;free(s);       return true;
}

相关文章:

数据结构(三)——栈

三、栈、队列和数组 3.1 栈 3.1.1 栈的基本概念 线性表是具有相同数据类型的n(n≥0)个数据元素的有限 序列,其中n为表长,当n 0时线 性表是一个空表。若用L命名线性表,则其一般表示为 L (a1, a2, … , ai , ai1, ……...

【Redis知识点总结】(五)——Redis实现分布式锁

Redis知识点总结(五)——Redis实现分布式锁 setnxsetnx expiresetnx expire lua脚本set nx exset nx ex 随机值set nx ex 随机值 lua脚本set ex nx 随机值 lua脚本 锁续期RedissonRedLock 在Redis的众多应用场景中,分布式锁是Redis比…...

CSS 绝对定位 position:absolute

什么是CSS绝对定位absolute定位? 绝对定位absolute定位是CSS中的一种定位方式,可以将元素精确定位到一个确定的点,这与元素在文档流上的自然位置无关。相比起其他定位方式,绝对定位很灵活性,它可以将元素脱离文档流&am…...

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:RelativeContainer)

相对布局组件,用于复杂场景中元素对齐的布局。 说明: 该组件从API Version 9开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 规则说明 容器内子组件区分水平方向,垂直方向: 水平方向为left&…...

Android制作微信添加多个图片,放大图片

1.添加依赖 implementation com.github.bumptech.glide:glide:4.12.0 //裁剪图片等等 implementation androidx.recyclerview:recyclerview:1.1.0 //recycleview依赖 2.使用recycleview <androidx.recyclerview.widget.RecyclerViewandroid:id"id/recyclerView"…...

iOS runtime理解和应用场景

一、runtime的动态性 OC的运行时系统(Runtime System)提供了丰富的动态特性,包括类与对象的创建、消息发送与转发、方法的动态添加与替换、属性的动态合成等。通过使用运行时库提供的API,可以在运行时获取和操作类与对象的信息,实现各种动态性的功能。 我对 Runtime 的理…...

画图实战-Python实现某产品全年销量数据多种样式可视化

画图实战-Python实现某产品全年销量数据多种样式可视化 学习心得Matplotlib说明什么是Matplotlib&#xff1f;Matplotlib特性Matplotlib安装 产品订单量-折线图某产品全年订单量数据数据提取和分析绘制折线图 产品订单&销售额-条形图某产品全年订单&销售额数据绘制条形…...

YOLOv9详解

1.概述 在逐层进行特征提取和空间转换的过程中&#xff0c;会损失大量信息&#xff0c;例如图中的马在建模过程中逐渐变得模糊&#xff0c;从而影响到最终的性能。YOLOv9尝试使用可编程梯度信息PGI解决这一问题。 具体来说&#xff0c; PGI包含三个部分&#xff0c;&#xff0…...

CRON 定时任务

检测是否安装了 cron systemctl status crond 如果没有安装使用 sudo yum install cronie 编辑 crontab -e * * * * * php /path/your.php Esc键 然后输入 :q 退出 :wq 保存并退出 第一个 * 表示分钟&#xff0c;表示每分钟执行一次。第二个 * 表示小时&#xff0c;表示每…...

环境安装篇 之 Kind 搭建 kubernetes 测试集群

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 环境安装 系列文章&#xff0c;介绍 使用Kind工具 快速安装 kubernetes 测试集群的详细步骤 1.Kind简介 Kind 是一个使用 Docker 容器“节点”运行本地 Kubernetes 集群的工具。Kind 主要用于测试kubernetes本…...

每日五道java面试题之mybatis篇(四)

目录&#xff1a; 第一题. 映射器#{}和${}的区别第二题. 模糊查询like语句该怎么写?第三题. 在mapper中如何传递多个参数?第四题. Mybatis如何执行批量操作第五题 MyBatis框架适用场景 第一题. 映射器#{}和${}的区别 #{}是占位符&#xff0c;预编译处理&#xff1b;${}是拼接…...

camunda流程引擎的插件如何使用

camunda工作流引擎是一个开放的架构&#xff0c;除了流程引擎默认提供的功能外&#xff0c;开发者可以通过流程插件机制&#xff0c;对流程引擎功能进行扩展。即流程引擎插件是流程引擎配置的扩展。插件必须提供 ProcessEnginePlugin 接口的实现。 下面以全局任务事件监听器为…...

Vue打包问题汇总:legacy、runtime.js

问题一&#xff1a;Vue3.x的版本中build后dist文件中出现legacy的js文件 解决办法是添加兼容的浏览器 package.json "browserslist": ["> 1%","last 2 versions","not dead","not ie 11" ]参考 Vue3.x的版本中build后…...

挑战杯 车位识别车道线检测 - python opencv

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) …...

c++面经

1. 僵尸进程 僵尸进程&#xff08;Zombie Process&#xff09;在操作系统中指的是那些已经执行完毕&#xff0c;但其父进程尚未对其进行善后处理&#xff08;例如读取子进程的状态信息或者执行回收资源的操作&#xff09;的进程。在Unix和类Unix系统&#xff0…...

js中副作用的消除还解决了并行计算带来的竞争问题,具体是如何解决的

在JavaScript中&#xff0c;副作用是指对外部环境产生的可观察的变化&#xff0c;例如修改全局变量、修改DOM元素等。副作用的存在可能导致代码的可维护性和可测试性下降&#xff0c;并且在并行计算中可能引发竞争问题。 不纯的函数有可能访问同一块资源&#xff0c;如果先后调…...

3/14/24数据结构、线性表

目录 数据结构 数据结构三要素 逻辑结构 存储结构 数据运算 时间复杂度 空间复杂度 线性表 线性表定义 静态分配 动态分配 线性表插入 线性表删除 十天的时间学完了C语言督学课程&#xff0c;最后终于是可以投入到408的科目学习当中。关于数据结构和算法的学习很多部…...

软件测试面试200问,面试看这就够了。。。

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Part1 1、你的测试职业发展是什么&#xff1f; 测试经验越多&#xff0c;测试能力越高。所以我…...

力扣● 583. 两个字符串的删除操作 ● 72. 编辑距离 ● 编辑距离总结篇

● 583. 两个字符串的删除操作 注意审题&#xff1a; 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 删除最少的字符使两者相同&#xff0c;说明留下来的就是最大公共子序列。不要求…...

Git速成

文章目录 Git 分布式版本控制工具课程内容1. 前言1.1 什么是Git1.2 使用Git能做什么 2. Git概述2.1 Git简介2.2 Git下载与安装 3. Git代码托管服务3.1 常用的Git代码托管服务3.2 码云代码托管服务3.2.1 注册码云账号3.2.2 登录码云3.2.3 创建远程仓库3.2.4 邀请其他用户成为仓库…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要&#xff0c;uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件&#xff0c;需要安装才能使用。 一、安装扩展插件 安装方法&#xff1a; 1.访问uniapp官方文档组件部分&#xff1a;组件使用的入门教程 | uni-app官网 点击左侧…...

嵌入式面试常问问题

以下内容面向嵌入式/系统方向的初学者与面试备考者,全面梳理了以下几大板块,并在每个板块末尾列出常见的面试问答思路,帮助你既能夯实基础,又能应对面试挑战。 一、TCP/IP 协议 1.1 TCP/IP 五层模型概述 链路层(Link Layer) 包括网卡驱动、以太网、Wi‑Fi、PPP 等。负责…...