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

#数据结构(二)--栈和队列

栈和队列

一栈

1.栈的顺序存储结构

特点:先进后出

栈是一种只能在一端进行插入或删除操作的线性表。

表中允许插入删除操作的一端为栈顶(top),表的另一端为栈底(bottom),

1 结构体的定义
#include <stdio.h>
typedef int ElemType;
#define MAX_SIZE 100typedef struct {int data[MAX_SIZE]; // 用于存储栈中的元素int top; // 栈顶指针,指向栈顶元素的索引
} SqStack;
2 初始化栈

栈顶指针赋值为-1

void InitStack(SqStack *&s) {s = (SqStack *) malloc(sizeof(SqStack));//申请一个顺序栈空间s->top = -1;//栈顶指针赋值为-1
}
3 销毁栈

释放节点空间

void DestroyStack(SqStack *&s) {free(s);
}
4 判断栈是否为空

指针为-1

bool StackEmpty(SqStack *&s) {return (s->top == -1);
}
5 进栈

先判断栈是否为满

注意先将指针++,再对栈顶元素进行赋值

bool PushStack(SqStack *&s, ElemType e) {if (s->top == MAX_SIZE - 1) {//栈满的情况return false;}s->top++;s->data[s->top] = e;//先加再赋值(s-data[++s->top])return true;
}
6 出栈

先对栈元素赋值,再将栈顶指针--

bool Pop(SqStack *&s, ElemType &e) {if (s->top == -1) {//栈空的情况return false;}e=s->data[s->top];s->top--;return true;
}
7 获取栈顶元素
bool GetTop(SqStack *s,ElemType &e){if (s->top==-1)return false;e=s->data[s->top];return true;
}
补充:共享栈
  1. 顺序栈采用一个数组存放栈中的元素。如果需要用到两个类型相同的栈,这时若为它们各自开辟一个数组空间,极有可能出现这样的情况:第一个栈已经满了,再进栈就溢出了,而另一个栈还有许多的空间。
  2. 共享栈是为了更有效地利用存储空间,两个栈的空间相互调节,只有在整个存储空间被占满时才会发生上溢。其存储数据的时间复杂度均为O(1),所以对存取效率没有什么影响。
  3. 栈空条件:栈0空为top==-1;栈1空为top1==MaxSize.
  4. 栈满条件:top==top1-1
  5. 元素进栈操作:进栈0操作为top0++;data[top0]=x;进栈1操作为top1--;data[top1]=x
  6. 元素出栈操作:出栈0操作为x=data[top0];top0--;出栈1操作为x=data[top1];top1++
  7. 在上述操作中,data数组表示共享栈的存储空间,top0和top1分别为两个栈的栈顶指针,这样该共享栈通过data,top0和top1来标识,也可以将他们设计为一个结构体类型。

2.栈的链式存储结构

栈中的数据元素的逻辑关系呈线性关系,所以栈可以像线性表一样采用链式存储结构

链栈通过单链表实现

不存在栈满上溢的情况,可以一直添加。

typedef struct linknode
{//定义链表节点数据ElemType data;//定义指针域,单链表的后继指针域struct linknode *next; 
}LiStack;

栈的四要素:

  • 栈空的条件:

s->next==NULL

bool StackEmpty(LiStack *s)
{return(s->next == NULL);
}
  • 栈满的条件:

链栈不存在满的情况

  • 进栈的条件

将带新元素的节点插入

//定义链表节点指针
LiStack *p;
//为新节点申请空间
p = (LiStack *)malloc(sizeof(LiStack));
//为新节点的数据区赋值
p -> data = e;
//头插法
//将新节点后继指针指向下一个节点 ,下一个节点插入前存放在头结点的后继指针
p -> next = s ->next;
//然后将头结点的后继指针指向新节点
s->next = p;
  • 出栈的条件:

将栈顶节点删除

//传入要出栈的链栈 , 传入要出栈的指针元素
bool Pop(LiStack *&s , ElemType &e)
{//用指针指向要出栈的元素,就是头结点的后继节点LiStack *p;//如果s->next 为空,则表明为空栈 ,无法出栈元素if(s->next == NULL){return false;}//如果经过上面条件的验证,s->next不为空,则接着往下走//先定位要出栈的元素p = s->next;	//头结点的后继节点e = p->data;	//栈顶数据传出//开始删除头结点的后继节点 p,也就是头结点指向要删除节点的下一个节点s->next = p->next;//然后释放 p 空间free(p);return true;
}

二 队列

特点:先进先出

队列只允许在一端进行插入另一端进行删除,允许插入的时队尾,允许删除的时队头

插入元素称为入队,删除元素称为出队。

1 顺序队列

  • 用一组地址连续的存储单元,以此存放从队头到队尾的数据元素,称为顺序队列。
  • 需要附设两个指针,一个队头指针(front)一个队尾指针(rear),分别指向队头队尾。

  • 初始时front和rear均为-1
  • 元素进队rear加1
  • front指向队首元素的前一位置
  • 队满条件:rear==MaxSize-1
  • 队空条件:front==rear
  • 进队操作:元素进队rear++,data[rear]=e
  • 出队操作:元素出队front++,e=data[front]

顺序队中实现队列的基本运算算法

结构体声明

typedef struct {ElemType data[MaxSize];//存放队中元素int front,rear;//队头和队尾指针
}SqQueue;
1 初始化

构造一个空队列q,将front和rear指针均设置为初始状态-1

void InitQueue(SqQueue *&q){q=(sqQueue *)malloc(sizeof(SqQueue));q->front=q->rear=-1;
}
2 入队

在队不满的情况下,先将队尾指针rear++,再将元素添加到该位置

bool enQueue(SqQueue *&q, ElemType e) {if (q->rear == MaxSize - 1)return false;q->rear++;q->data[q->rear] = e;return true;
}
3 出队

在队不空的情况下,将队首元素front++,再将该位置的元素赋值给e

bool deQueue(SqQueue *&q, ElemType &e) {if (q->front == q->rear)return false;q->front++;e = q->data[q->front];return true;
}

2 环形队列:

这是因为采用了rear=MaxSize-1作为队满条件的缘故,当出现这种情况可能会出现还有空间没有填满的情况。这种情况称为假溢出。

解决方案:环形队列

实际上地址一定是连续的不可能是环形的,这里是通过逻辑方式实现环形队列

  • rear=(rear+1)%MaxSize
  • front=(front+1)%MaxSize

  • 队空条件:rear==front
  • 队满条件:(rear+1)%MaxSize==front
  • 进队操作:rear=(rear+1)%MaxSize,并且将e放在rear处
  • 出队操作:front=(front+1)%MaxSize,将front位置e取出
  • 这种情况下会比原先少放一个元素

相关计算:

3 链队

  • 采用链表存储的称为链队。

相关操作:

单链表中数据节点类型DataNode声明如下

typedef struct qnode{ElemType data;struct qnode *next;
}DataNode;

链队节点类型LinkQuNode声明如下

typedef struct {DataNode *front;DataNode *rear;
}LinkQuNode;

链队四要素:

  • 链队为空的判断条件:front=rear=NULL
  • 链队为满的判断条件:不考虑
  • 链队插入的判断条件:将含e的单链表节点插入至链表结尾
  • 链队删除的判断条件:将单链表的首元节点删除

代码实现;

#include <stdio.h>
#include <cstdlib>typedef int ElemType;
typedef struct qnode {ElemType data;//存放元素struct qnode *next;//下一个节点指针
} DataNode;//数据节点的类型typedef struct {DataNode *front;DataNode *rear;
} LinkQuNode;
初始化:
void InitQueue(LinkQuNode *&q) {q = (LinkQuNode *) malloc(sizeof(LinkQuNode));q->front = q->rear = NULL;
}
判断是否为空:
bool QueueEmpty(LinkQuNode *q) {return (q->rear == NULL);
}
进队列
bool enQueue(LinkQuNode *&q, ElemType e) {DataNode *p;p = (DataNode *) malloc(sizeof(DataNode));p->data = e;p->next = NULL;if (q->rear == NULL)q->front = q->rear = p;else {q->rear->next = p;q->rear = p;}return true;
}
出队列
bool deQueue(LinkQuNode *&q, ElemType &e) {DataNode *t;if (q->rear == NULL)return false;t = q->front;if (q->front == q->rear)q->front = q->rear = NULL;elseq->front = q->front->next;e = t->data;free(t);return true;
}

4 双端队列

所谓双端队列是指两端都可以进行进队和出队的操作的队列,将队列的两端分别成为前端和后端,两端都可以进队和出队。

相关文章:

#数据结构(二)--栈和队列

栈和队列 一栈 1.栈的顺序存储结构 特点&#xff1a;先进后出 栈是一种只能在一端进行插入或删除操作的线性表。 表中允许插入删除操作的一端为栈顶&#xff08;top&#xff09;&#xff0c;表的另一端为栈底&#xff08;bottom&#xff09;&#xff0c; 1 结构体的定义 …...

react18中的函数组件底层渲染原理分析

react 中的函数组件底层渲染原理 react组件没有局部与全局之分&#xff0c;它是一个整体。这点跟vue的组件化是不同的。要实现 react 中的全局组件&#xff0c;可以将组件挂在react上&#xff0c;这样只要引入了react&#xff0c;就可以直接使用该组件。 函数式组件的创建 …...

提升产品竞争力之--IPD产品成本篇

在汉捷的咨询过程中&#xff0c;很多企业老总交流时都会提起这个抱怨&#xff1a;“现在产品竞争太激烈了&#xff0c;客户买产品首先看价格&#xff0c;你价格高一点就买别家的啦……” 汉捷咨询在前文谈到“通过定义产品包需求&#xff0c;来提升产品竞争力。差异化开发&…...

如何在Debian操作系统上安装Docker

本章教程&#xff0c;主要介绍如何在Debian 11 系统上安装Docker。主要使用一键安装Docker脚本和一键卸载脚本来完成。 一、安装Docker #!/bin/bashRED\033[0;31m GREEN\033[0;32m YELLOW\033[0;33m BLUE\033[0;34m NC\033[0mCURRENT_DIR$(cd "$(dirname "$0")…...

ArrayList和Array、LinkedList、Vector 间的区别

一、ArrayList 和 Array 的区别 ArrayList 内部基于动态数组实现&#xff0c;比 Array&#xff08;静态数组&#xff09; 使用起来更加灵活&#xff1a; ArrayList 会根据实际存储的元素动态地扩容或缩容&#xff0c;而 Array 被创建之后就不能改变它的长度了。ArrayList 允许…...

Linux开发环境配置(下)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…...

系统开发常用命令合集

本文还会持续更新&#xff0c;大家可以点赞收藏~ ifconfig ifconfigwlan0表示无线网络接口 eth0表示以太网接口&#xff08;有线&#xff09; HWaddr是接口的物理地址&#xff08;MAC地址&#xff09; inet addr是接口的IPv4地址 Bcast是广播地址&#xff0c;Mask是子网掩码 …...

Termius工具在MAC的使用出现的问题:

Termius工具在MAC的使用出现的问题&#xff1a; 在使用SFTP时&#xff0c;出现不了本地的文件的位置 解决方案&#xff1a; 在Apple store下载的使用不了LOCAL SFTP&#xff0c; 需要在网页上进行下载才可以&#xff1a; 官网下载地址&#xff1a;https://termius.com/down…...

浅析Android中View的绘制流程

前言 在《浅析Android中View的测量布局流程》中分析了VSYNC信号到达App进程之后开启的View布局过程&#xff0c;经过对整个View树进行遍历进行测量和布局&#xff0c;最终确定View的大小以及在屏幕中所处的位置。但是如果用户想在屏幕上看到View的内容还需要经过绘制来生成图形…...

pikachu靶场- 文件上传unsafe upfileupload

pikachu靶场- unsafe upfileupload 概述client checkMIME typegetimagesize() 概述 不安全的文件上传漏洞概述 文件上传功能在web应用系统很常见&#xff0c;比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后&#xff0c;后台会对上传的文件进行判断…...

java中this的内存原理是?

在Java中&#xff0c;this关键字是一个特殊的引用&#xff0c;指向当前对象的实例。它在以下几个方面发挥重要作用&#xff1a; 指向当前对象&#xff1a;this可以用来访问当前对象的属性和方法&#xff0c;尤其在参数命名与实例变量重名时&#xff0c;用于区分。 构造函数&a…...

Matlab 车牌识别技术

1.1设计内容及要求&#xff1a; 课题研究的主要内容是对数码相机拍摄的车牌&#xff0c;进行基于数字图像处理技术的车牌定位技术和车牌字符分割技术的研究与开发&#xff0c;涉及到图像预处理、车牌定位、倾斜校正、字符分割等方面的知识,总流程图如图1-1所示。 图1-1系统总…...

CUDA-求最大值最小值atomicMaxatomicMin

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 实现原理 atomicMax和 atomicMin是 CUDA 中的原子操作&#xff0c;用于在并行计算中安全地更新共享变量的最大值和最小值。它们确…...

新的Midjourney就是一个增强版的Photoshop,你现在可以轻松的用它换衣服、换发型了

好久没有聊 Midjourney 了&#xff0c;昨晚他们发布了一项引人注目的新功能&#xff1a;AI 图像编辑&#xff0c;一个基于网页的加强版的 Photoshop 呼之欲出&#xff0c;让我大为震撼&#xff0c;也让用户们赞叹不已。 基于现有图像进行参考&#xff0c;进而生成新的图片&…...

Linux系统安装软件的4种方式【源码配置编译安装、yum安装、rpm包安装、二进制软件包安装(.rpm/.tar.gz/.tgz/.bz2)】

一.源码安装 linux安装软件采用源码安装灵活自由&#xff0c;适用于不同的平台&#xff0c;维护也十分方便。 &#xff08;一&#xff09;源码安装流程  源码的安装一般由3个步骤组成&#xff1a; 1.配置&#xff08;configure&#xff09; Configure是一个可执行脚本…...

基于Spring Boot的洪涝灾害应急信息管理系统设计与实现

摘要 近年来&#xff0c;全球气候变化加剧&#xff0c;洪涝灾害频发&#xff0c;给各国的经济发展和人民生活带来了巨大的威胁。为了提高洪涝灾害的应急响应能力&#xff0c;开发高效的应急信息管理系统变得至关重要。本文基于Spring Boot框架&#xff0c;设计并实现了一个洪涝…...

912.排序数组(桶排序)

目录 题目解法 题目 给你一个整数数组 nums&#xff0c;请你将该数组升序排列。 你必须在 不使用任何内置函数 的情况下解决问题&#xff0c;时间复杂度为 O(nlog(n))&#xff0c;并且空间复杂度尽可能小。 解法 class Solution { public:vector<int> sortArray(vect…...

IPC 进程间通信 消息队列

操作系统内核中采用一个链式队列管理消息,每个节点就对应一个消息&#xff1a; 操作系统规定了单个消息的数据长度不能超过8k(8192个字节)&#xff0c;一个消息队列的表长(节点数)最多不超过256个 利用消息队列进行通信的特点&#xff1a; 1. 全双工&#xff1a;任何参与通信的…...

opencv 图像翻转- python 实现

在做图像数据增强时会经常用到图像翻转操作 flip。 具体代码实现如下&#xff1a; #-*-coding:utf-8-*- # date:2021-03 # Author: DataBall - XIAN # Function: 图像翻转import cv2 # 导入OpenCV库path test.jpgimg cv2.imread(path)# 读取图片 cv2.namedWindow(image,1) …...

使用DolphinScheduler接口实现批量导入工作流并上线

使用DS接口实现批量导入工作量并上线脚本 前面实现了批量生成DS的任务&#xff0c;当导入时发现只能逐个导入&#xff0c;因此通过接口实现会更方便。 DS接口文档 DS是有接口文档的地址是 http://IP:12345/dolphinscheduler/swagger-ui/index.html?languagezh_CN&lang…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...

【深尚想】TPS54618CQRTERQ1汽车级同步降压转换器电源芯片全面解析

1. 元器件定义与技术特点 TPS54618CQRTERQ1 是德州仪器&#xff08;TI&#xff09;推出的一款 汽车级同步降压转换器&#xff08;DC-DC开关稳压器&#xff09;&#xff0c;属于高性能电源管理芯片。核心特性包括&#xff1a; 输入电压范围&#xff1a;2.95V–6V&#xff0c;输…...

Tauri2学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引&#xff1a;https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多&#xff0c;我按照Tauri1的教程来学习&…...

虚幻基础:角色旋转

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 移动组件使用控制器所需旋转&#xff1a;组件 使用 控制器旋转将旋转朝向运动&#xff1a;组件 使用 移动方向旋转 控制器旋转和移动旋转 缺点移动旋转&#xff1a;必须移动才能旋转&#xff0c;不移动不旋转控制器…...