数据结构 | 栈和队列

文章目录

  • 栈和队列
    • 1. 栈:后进先出(LIFO)的数据结构
      • 1.1 概念与结构
      • 1.2 栈的实现
    • 2. 队列:先进先出(FIFO)的数据结构
      • 2.1 概念与结构
      • 2.2 队列的实现
    • 3. 栈和队列算法题
      • 3.1 有效的括号
      • 3.2 用队列实现栈
      • 3.3 用栈实现队列
      • 3.4 设计循环队列
    • 结论

栈和队列

在计算机科学中,栈和队列是两种基本且重要的数据结构,它们在处理数据存储和访问顺序方面有着独特的规则和应用。本文将详细介绍栈和队列的概念、结构、实现方式,并通过几个经典的算法题目来展示它们的实际应用。

1. 栈:后进先出(LIFO)的数据结构

1.1 概念与结构

栈是一种特殊的线性表,它只允许在一端(称为栈顶)进行插入和删除操作。另一端称为栈底。栈中的数据元素遵循后进先出(LIFO)的原则,即最后进入的数据项最先被移除。

  • 压栈(进栈/入栈):数据插入操作在栈顶进行。
  • 出栈:数据删除操作也在栈顶进行。

1.2 栈的实现

栈可以使用数组或链表来实现,但数组由于在尾部插入数据的效率较高,通常更受青睐。以下是栈的基本操作的C语言实现:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>typedef int STDataType;typedef struct Stack {STDataType* array;int top;int capacity;
} ST;// 初始化栈
void STInit(ST* ps, int capacity) {ps->array = (STDataType*)malloc(sizeof(STDataType) * capacity);ps->top = -1;ps->capacity = capacity;
}// 销毁栈
void STDestroy(ST* ps) {free(ps->array);ps->array = NULL;ps->top = -1;ps->capacity = 0;
}// 入栈
void STPush(ST* ps, STDataType x) {if (ps->top >= ps->capacity - 1) {// 栈满,扩容或者报错return;}ps->array[++ps->top] = x;
}// 出栈
void STPop(ST* ps) {if (ps->top < 0) {// 栈空,报错return;}ps->top--;
}// 取栈顶元素
STDataType STTop(ST* ps) {if (ps->top < 0) {// 栈空,报错return -1;}return ps->array[ps->top];
}// 获取栈中有效元素个数
int STSize(ST* ps) {return ps->top + 1;
}// 栈是否为空
bool STEmpty(ST* ps) {return ps->top < 0;
}

2. 队列:先进先出(FIFO)的数据结构

2.1 概念与结构

队列是一种只允许在一端(称为队尾)进行插入操作,在另一端(称为队头)进行删除操作的线性表。队列遵循先进先出(FIFO)的原则。

  • 入队列:数据插入操作在队尾进行。
  • 出队列:数据删除操作在队头进行。

2.2 队列的实现

队列通常使用链表实现,因为如果使用数组,出队操作(尤其是在数组头部)的效率会较低。以下是队列的基本操作的C语言实现:

typedef int QDataType;typedef struct QueueNode {QDataType val;struct QueueNode* next;
} QNode;typedef struct Queue {QNode* front;QNode* rear;int size;
} Queue;// 初始化队列
void QueueInit(Queue* pq) {pq->front = pq->rear = (QNode*)malloc(sizeof(QNode));if (pq->rear) {pq->rear->next = NULL;}pq->size = 0;
}// 销毁队列
void QueueDestroy(Queue* pq) {QNode* current = pq->front;QNode* next;while (current != NULL) {next = current->next;free(current);current = next;}pq->front = pq->rear = NULL;pq->size = 0;
}// 入队列,队尾添加元素
void QueuePush(Queue* pq, QDataType x) {QNode* newNode = (QNode*)malloc(sizeof(QNode));if (newNode == NULL) {return; // 内存分配失败}newNode->val = x;newNode->next = NULL;if (pq->rear) {pq->rear->next = newNode;}pq->rear = newNode;if (pq->front->next == NULL) { // 队列原来为空pq->front->next = newNode;}pq->size++;
}// 出队列,队头删除元素
void QueuePop(Queue* pq) {if (QueueEmpty(pq)) {return; // 队列为空,无法出队}QNode* temp = pq->front->next;QNode* prev = pq->front;if (temp == pq->rear) { // 只有一个元素pq->front = pq->rear = NULL;} else {pq->front->next = temp->next;if (temp == pq->rear) {pq->rear = prev;}}free(temp);pq->size--;
}// 取队头数据
QDataType QueueFront(Queue* pq) {if (QueueEmpty(pq)) {return -1; // 队列为空}return pq->front->next->val;
}// 取队尾数据
QDataType QueueBack(Queue* pq) {if (QueueEmpty(pq)) {return -1; // 队列为空}return pq->rear->val;
}// 队列判空
bool QueueEmpty(Queue* pq) {return (pq->size == 0);
}// 队列有效元素个数
int QueueSize(Queue* pq) {return pq->size;
}

3. 栈和队列算法题

3.1 有效的括号

题目描述:给定一个只包括 '(', ')', '{', '}', '[', ']' 的字符串,判断字符串是否有效。

思路:使用栈来解决这个问题。遍历字符串中的每个字符,如果是左括号,就压入栈中。如果是右括号,则检查栈顶是否有对应的左括号,如果有,则弹出栈顶元素并继续遍历;如果没有,说明字符串无效。最后,如果栈为空,则字符串有效;否则,无效。

力扣题目链接:有效的括号

3.2 用队列实现栈

题目描述:使用队列实现栈的下列操作:push、pop、top 和 empty。

思路:使用两个队列来模拟栈的行为。对于入栈操作,直接添加到队列中;对于出栈操作,将除了最新的元素外的所有元素重新入队一次,最新的元素即为要出栈的元素。这样可以保证队列的 FIFO 特性来模拟栈的 LIFO 特性。

力扣题目链接:用队列实现栈

3.3 用栈实现队列

题目描述:使用栈实现队列的下列操作:push、pop、peek 和 empty。

思路:使用两个栈来实现队列的功能。入队操作直接压入一个栈中,出队操作则涉及到两个栈的配合:将一个栈中的所有元素依次弹出并压入另一个栈中,这样第一个弹出的元素就是队列的前端元素,可以作为出队操作的返回值。

力扣题目链接:用栈实现队列

3.4 设计循环队列

循环队列是一种特殊的队列,它可以高效地利用数组空间,避免队列满时的额外处理。循环队列可以通过Q.rear = Q.front来区分队空和队满的情况。

结论

栈和队列不仅是数据结构的基础,也是许多算法和应用的核心。理解它们的原理和实现对于任何软件开发者来说都是至关重要的。通过实际的编程练习和算法题目,我们可以进一步加深对这些概念的理解。

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

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

相关文章

中国矿业大学《2023年868+2007年自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《25届中国矿业大学868自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2007年复试真题 2023年初试真题 Part1&#xff1a;完整版真题 2007年复试真题 2…

【Python基础】Python错误和异常处理(详细实例)

本文收录于 《Python编程入门》专栏&#xff0c;从零基础开始&#xff0c;分享一些Python编程基础知识&#xff0c;欢迎关注&#xff0c;谢谢&#xff01; 文章目录 一、前言二、Python中的错误类型三、Python异常处理机制3.1 try-except语句3.2 try-except-else语句3.3 try-fi…

TiDB 扩容过程中 PD 生成调度的原理及常见问题丨TiDB 扩缩容指南(一)

导读 作为一个分布式数据库&#xff0c;扩缩容是 TiDB 集群最常见的运维操作之一。本系列文章&#xff0c;我们将基于 v7.5.0 具体介绍扩缩容操作的具体原理、相关配置及常见问题的排查。 通常&#xff0c;我们根据当前资源状态来决定是否需要调整 TiKV 节点的规模&#xff0…

探索螺钉设计:部分螺纹与全螺纹,哪种更适合你的项目?

为什么有些螺钉有部分螺纹? 螺钉由头部、柄部和尖端组成&#xff0c;是世界上zui常用的紧固件之一。与螺栓一样&#xff0c;它们旨在将多个对象或表面连接在一起。但是&#xff0c;在比较不同类型的螺钉时&#xff0c;您可能会注意到其中一些都具有部分螺纹杆。 什么是螺柄&a…

Python | Leetcode Python题解之第397题整数替换

题目&#xff1a; 题解&#xff1a; class Solution:def integerReplacement(self, n: int) -> int:ans 0while n ! 1:if n % 2 0:ans 1n // 2elif n % 4 1:ans 2n // 2else:if n 3:ans 2n 1else:ans 2n n // 2 1return ans

Python_两个jpg图片文件名称互换

项目场景 处理Adobe Photoshop导出的两个切片的顺序错误问题 小编在进行图片切片处理的时候&#xff0c;发现用PS导出的切片顺序错误&#xff0c;例如用PS导出的切片分别为test_01.jpg&#xff0c;test_02.jpg&#xff0c;但实际的使用需求是将两个图片的顺序调换&#xff0c…

self-play RL学习笔记

让AI用随机的路径尝试新的任务&#xff0c;如果效果超预期&#xff0c;那就更新神经网络的权重&#xff0c;使得AI记住多使用这个成功的事件&#xff0c;再开始下一次的尝试。——llya Sutskever 这两天炸裂朋友圈的OpenAI草莓大模型o1和此前代码能力大幅升级的Claude 3.5&…

基于less和scss 循环生成css

效果 一、less代码 复制代码 item-count: 12; // 生成多少个 .item 类.item-loop(n) when (n > 0) {.icon{n} {background: url(../../assets/images/menu/icon{n}.png) no-repeat;background-size: 100% 100%;}.item-loop(n - 1);}.item-loop(item-count);二、scss代码 f…

【人工智能】Transformers之Pipeline(十七):文本分类(text-classification)

目录 一、引言 二、文本分类&#xff08;text-classification&#xff09; 2.1 概述 2.2 DistilBERT—BERT 的精简版&#xff1a;更小、更快、更便宜、更轻便 2.3 应用场景​​​​​​​ 2.4 pipeline参数 2.4.1 pipeline对象实例化参数 2.4.2 pipeline对象使用参数 …

【Hot100】LeetCode—287. 寻找重复数

目录 1- 思路题目识别快慢指针-类比链表判环 2- 实现⭐31. 下一个排列——题解思路 3- ACM 实现 原题链接&#xff1a;287. 寻找重复数 1- 思路 题目识别 识别1 &#xff1a;给定一个数组&#xff0c;寻找数组中的重复数。必须用 O(1) 的空间复杂度&#xff0c;且不能修改数组…

VMware Fusion Pro 13 Mac版虚拟机 安装Win11系统教程

Mac分享吧 文章目录 Win11安装完成&#xff0c;软件打开效果一、VMware安装Windows11虚拟机1️⃣&#xff1a;准备镜像2️⃣&#xff1a;创建虚拟机3️⃣&#xff1a;虚拟机设置4️⃣&#xff1a;安装虚拟机5️⃣&#xff1a;解决连不上网问题 安装完成&#xff01;&#xff0…

fuxa搭建与使用(web组态)

1. 安装Node.js -> npm安装 参考网址&#xff1a;https://blog.csdn.net/WHF__/article/details/129362462 一、安装运行 C:\WINDOWS\system32>node -v v20.17.0 C:\WINDOWS\system32>npm -v 10.8.2 二、环境配置 在安装路径&#xff08;D:\Program_Files\nodejs&a…

[数据集][目标检测]车油口挡板开关闭合检测数据集VOC+YOLO格式138张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;138 标注数量(xml文件个数)&#xff1a;138 标注数量(txt文件个数)&#xff1a;138 标注类别…

【2024.08】图模互补:知识图谱与大模型融合综述-笔记

阅读目的&#xff1a;假设已有一个知识图谱&#xff0c;如何利用图谱增强模型的问答&#xff0c;如何检索知识图谱、知识图谱与模型的文本如何相互交互、如何利用知识图谱增强模型回答的可解释性。 从综述中抽取感兴趣的论文进一步阅读。 来源&#xff1a;图模互补&#xff1…

Docker零基础入门

参考课程https://www.bilibili.com/video/BV1VC4y177re/?vd_source=b15169a302bee35f484245aecc69d4dd 参考书籍Docker 实践 - 面向 AI 开发人员的 Docker 实践 (dockerpractice.readthedocs.io) 1. 什么是Docker 1.1. Docker起源 随着计算机的发展,计算机上已经可以运行多…

CAN通讯常见错误纠正

CAN通讯常见错误 1.在使用CAN设备进行数据通讯时&#xff0c;有时候参数配置不当可能就会导致通讯的失败&#xff0c;如下图1所示&#xff0c;出现通信错误的原因是两个设备的波特率配置不一致导致。 图1 2.有时候在配置参数的时候&#xff0c;不能只关注波特率速度配置一致就…

Script-server: 一款开源的脚本管理工具,为你的Python脚本提供一个直观的 Web UI

在日常工作中&#xff0c;我们经常会使用各种脚本来自动化任务&#xff0c;提升效率。但传统的脚本管理方式往往伴随着一些困扰&#xff1a;复杂的命令行操作、难以理解的脚本参数、缺乏直观的反馈等等。这些问题&#xff0c;让原本应该便捷的脚本管理变得繁琐。 Script-server…

太速科技-基于XC7Z100+AD9361的双收双发无线电射频板卡

基于XC7Z100AD9361的双收双发无线电射频板卡 一、板卡概述 基于XC7Z100AD9361的双收双发无线电射频板卡是基于Xilinx ZYNQ FPGA和ADI的无线收发芯片AD9361开发的专用功能板卡&#xff0c;用于4G小基站&#xff0c;无线图传&#xff0c;数据收发等领域。 二、板卡…

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第三期]

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第三期] 第三期介绍&#xff1a;频道模块之频道成员 目录 QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第三期]第三期介绍&#xff1a;频道模块之频道成员获取子频道在线成员数获取频道成员列表获取频道身份组成员列…

Java项目: 基于SpringBoot+mybatis+maven课程答疑系统(含源码+数据库+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven课程答疑系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…