什么是堆栈和队列?如何实现它们?
堆栈(Stack)和队列(Queue)是两种常见的线性数据结构,用于组织和管理数据。它们分别具有不同的特点和用途。本文将详细解释堆栈和队列的概念、特点以及如何实现它们。
堆栈(Stack)
什么是堆栈?
堆栈是一种线性数据结构,它基于"后进先出"(Last-In-First-Out,LIFO)的原则,意味着最后进入堆栈的元素将首先被移除。堆栈的操作只允许在一端进行,通常称为堆栈的顶部(Top)。堆栈的两个主要操作是入栈(Push)和出栈(Pop)。
- 入栈(Push):将一个元素添加到堆栈的顶部。
- 出栈(Pop):从堆栈的顶部移除一个元素,并返回被移除的元素。
堆栈的应用
堆栈在计算机科学和编程中有广泛的应用,以下是一些示例:
-
函数调用:计算机使用堆栈来跟踪函数调用和返回地址。每当调用一个函数,当前函数的状态(包括局部变量和执行位置)被压入堆栈,当函数返回时,状态被弹出堆栈以恢复到调用点。
-
表达式求值:堆栈可用于评估表达式,如算术表达式和布尔表达式。通过将操作数和操作符按照正确的顺序压入堆栈,可以轻松地计算表达式的结果。
-
内存管理:堆栈用于内存分配和释放,通常通过动态分配内存的指针在堆栈中进行跟踪。
-
回文检测:堆栈可用于检测字符串是否是回文(从前到后和从后到前都相同的字符串)。将字符串的字符依次入栈,然后与出栈的字符比较。
如何实现堆栈?
在C语言中,可以使用数组或链表来实现堆栈。以下是使用数组的简单堆栈实现示例:
#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100// 定义堆栈结构
struct Stack {int data[MAX_SIZE];int top;
};// 初始化堆栈
void initStack(struct Stack* stack) {stack->top = -1; // 初始化堆栈顶部指针为-1,表示堆栈为空
}// 入栈操作
void push(struct Stack* stack, int value) {if (stack->top < MAX_SIZE - 1) {stack->top++;stack->data[stack->top] = value;} else {printf("堆栈已满,无法入栈\n");}
}// 出栈操作
int pop(struct Stack* stack) {if (stack->top >= 0) {int value = stack->data[stack->top];stack->top--;return value;} else {printf("堆栈为空,无法出栈\n");return -1; // 返回一个错误值}
}// 查看堆栈顶部元素但不移除
int peek(struct Stack* stack) {if (stack->top >= 0) {return stack->data[stack->top];} else {printf("堆栈为空,无法查看顶部元素\n");return -1; // 返回一个错误值}
}int main() {struct Stack stack;initStack(&stack);push(&stack, 1);push(&stack, 2);push(&stack, 3);printf("堆栈顶部元素:%d\n", peek(&stack)); // 输出:3while (stack.top >= 0) {printf("%d ", pop(&stack)); // 输出:3 2 1}return 0;
}
上述代码定义了一个基于数组的堆栈结构,包括初始化堆栈、入栈、出栈和查看堆栈顶部元素的操作。在使用堆栈时,需要注意堆栈的大小限制,以避免堆栈溢出。
队列(Queue)
什么是队列?
队列是一种线性数据结构,基于"先进先出"(First-In-First-Out,FIFO)原则,意味着最早进入队列的元素将最先被移除。队列的操作通常包括入队(Enqueue)和出队(Dequeue)。
- 入队(Enqueue):将一个元素添加到队列的末尾。
- 出队(Dequeue):从队列的开头移除一个元素,并返回被移除的元素。
队列的应用
队列在计算机科学和编程中有广泛的应用,以下是一些示例:
-
任务调度:操作系统使用队列来调度进程和线程的执行顺序,确保公平分配CPU时间片。
-
广度优先搜索:在图算法中,队列用于实现广度优先搜索(BFS),以在图中搜索最短路径或解决其他问题。
-
缓冲区管理:队列用于管理输入和输出缓冲区,确保数据按照正确的顺序进行处理。
-
打印队列:打印机队列用于管理多个打印任务,以便按照提交顺序打印文档。
如何实现队列?
在C语言中,可以使用数组或链表来实现队列。以下是使用数组的简单队列实现示例:
#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100// 定义队列结构
struct Queue {int data[MAX_SIZE];int front; // 队列前部int rear; // 队列后部
};// 初始化队列
void initQueue(struct Queue* queue) {queue->front = 0; // 初始化队列前部指针为0queue->rear = -1; // 初始化队列后部指针为-1
}// 入队操作
void enqueue(struct Queue* queue, int value) {if (queue->rear < MAX_SIZE - 1) {queue->rear++;queue->data[queue->rear] = value;} else {printf("队列已满,无法入队\n");}
}// 出队操作
int dequeue(struct Queue* queue) {if (queue->front <= queue->rear) {int value = queue->data[queue->front];queue->front++;return value;} else {printf("队列为空,无法出队\n");return -1; // 返回一个错误值}
}// 查看队列前部元素但不移除
int peek(struct Queue* queue) {if (queue->front <= queue->rear) {return queue->data[queue->front];} else {printf("队列为空,无法查看前部元素\n");return -1; // 返回一个错误值}
}int main() {struct Queue queue;initQueue(&queue);enqueue(&queue, 1);enqueue(&queue, 2);enqueue(&queue, 3);printf("队列前部元素:%d\n", peek(&queue)); // 输出:1while (queue.front <= queue.rear) {printf("%d ", dequeue(&queue)); // 输出:1 2 3}return 0;
}
上述代码定义了一个基于数组的队列结构,包括初始化队列、入队、出队和查看队列前部元素的操作。与堆栈类似,在使用队列时,需要注意队列的大小限制,以避免队列溢出。
总结
堆栈和队列是两种常见的线性数据结构,它们分别基于"后进先出"(LIFO)和"先进先出"(FIFO)原则,具有不同的应用场景和特点。堆栈适用于需要追踪最近操作或状态的情况,而队列适用于需要按照顺序处理数据的情况。在C语言中,可以使用数组或链表来实现堆栈和队列,并通过入栈/入队和出栈/出队等操作来管理数据。理解堆栈和队列的概念以及如何实现它们是编程中的重要基础知识,可以帮助你更好地解决各种问题和任务。希望本文能帮助你入门堆栈和队列的使用。
相关文章:
什么是堆栈和队列?如何实现它们?
堆栈(Stack)和队列(Queue)是两种常见的线性数据结构,用于组织和管理数据。它们分别具有不同的特点和用途。本文将详细解释堆栈和队列的概念、特点以及如何实现它们。 堆栈(Stack) 什么是堆栈&…...

编译器自动生成的构造函数
背景 作为一个C小白,最近在看深度解析对象模型的时候,发现一个很久以来的认知错误:编译器会为没有定义构造函数的class生成一个默认构造函数。其实这个观点是错误的,编译器只会在四种情况下生成。 相关知识 一定要明确一个事情…...

SpringSecurity - 认证与授权、自定义失败处理、跨域问题、认证成功/失败处理器
SpringSecurity 文章目录 SpringSecurity一、 简介二、快速入门2.1 maven坐标2.2 访问请求 三、认证与授权3.1 认证3.1.1 登录检验流程3.1.2 SpringSecurity 完整流程3.1.3 认证流程详解3.1.4 校验3.1.5 要解决的问题3.1.6 准备工作3.1.7 实现3.1.7.1 数据库校验用户3.1.7.1.1 …...

自定义映射resultMap
自定义映射resultMap 自定义映射resultMap 自定义映射resultMapresultMap处理字段和属性的映射关系字段名和属性名不一致的情况,如何处理映射关系?1、为查询的字段设置别名,和属性名保持一致2、核心配置文件(mybatis-config.xml)中设置一个全局配置3、使…...

Android修行手册 - Android Studio去掉方法参数提示、变量类型提示、方法引用Usage提示
点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&…...

【车载开发系列】ECU Application Software程序刷新步骤
【车载开发系列】ECU Application Software程序刷新步骤 ECU Application Software程序刷新步骤 【车载开发系列】ECU Application Software程序刷新步骤一. Boot Software(引导软件)1)boot manager(启动管理器)2&…...
inject和provide的使用
官网介绍用法 V2.2.0 新增的方法 类型 provide:Object | () > Object inject:Array<string> | { [key: string]: string | Symbol | Object }介绍 这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖ÿ…...
2023年中国研究生数学建模竞赛D题
一、背景介绍 2021年9月22日,中共中央国务院正式发布《关于完整准确全面贯彻新发展理念做好碳达峰碳中和工作的意见》(以下简称《意见》),明确了中国双碳行动的顶层设计。 我国是世界上最大的发展中国家,为实现中华民…...

Unity制作曲线进度条
unity制作曲线进度条 大家好,我是阿赵。 在使用Unity引擎做进度条的时候,有时会遇到一个问题,如果进度条不是简单的横向、纵向或者圆形,而是任意的不规则形状,那该怎么办呢?比如这样的: 一…...
面试:C++ 11 智能指针
查询内存泄露方法 啥是内存泄露 内存泄露在维基百科中的解释如下: 在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误&…...
设计模式——3. 抽象工厂模式
1. 说明 抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种创建一组相关或依赖对象的方式,而无需指定它们的具体类。抽象工厂模式是工厂模式的扩展,它关注于创建一组相关的对象家族,而不仅仅是一个单一的对象。 抽象工厂模式通常涉及以下几个角…...

vscode 无法使用 compilerPath“D:.../bin/arm-none-eabi-g++.exe”解析配置。
最近在使用vscode搭建ODrive STM32开发环境,依次安装了以下内容: 1.Python3: 用于运行工程构建脚本 2.ST-Link/V2 Drivers: STLink/v2编程器的驱动 3.Visual Studio Code: 轻量级但功能强大的源代码编辑器 …...

Vue.js入门模板语法[上] 及Vue.js实现购物车---详细讲解
前言 前面我们学习了Vue的基础入门,接下来我们学习有关Vue的模板语法,学习Vue语法能提高我们的前端开发效率 Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML &a…...
windows下gvim的配置
一、vim配置文件 "查看自己的vimrc所在的目录 "在命令模式下 :echo $MYVIMRC"打开自己的vimrc文件 "在命令模式下 :e $MYVIMRC 二、排版 "查看自己当前的字体及大小 "在命令模式下 :set guifont?"设置默认的字体为仿宋_GB2312ÿ…...

基于复旦微的FMQL45T900全国产化ARM开发开发套件(核心板+底板)
TES745D是我司自主研制的一款基于上海复旦微电子FMQL45T900的全国产化ARM核心板(模块)。该核心板将复旦微的FMQL45T900(与XILINX的XC7Z045-2FFG900I兼容)的最小系统集成在了一个87*117mm的核心板上,可以作为一个核心模…...
Leetcode Top100(23)环形链表
给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索…...

线性代数基础-行列式
一、行列式之前的概念 1.全排列: 把n个不同的元素排成一列,称为n个元素的全排列,简称排列 (实际上就是我们所说的排列组合,符号是A,arrange) 2.标准序列: 前一项均小于后一项的序列…...

RT-Thread(学习)
RT-Thread是一款完全由国内团队开发维护的嵌入式实时操作系统(RTOS),具有完全的自主知识产权。经过16个年头的沉淀,伴随着物联网的兴起,它正演变成一个功能强大、组件丰富的物联网操作系统。 RT-Thread概述 RT-Threa…...
【MySQL】 MySQL 死锁问题分析优化器特性及优化方案
MySQL 死锁问题分析优化器特性及解决方案 MySQL 锁机制介绍 1、MySQL常用存储引擎的锁机制 MyISAM和MEMORY采用表级锁(table-level locking) BDB采用页面锁(page-level locking)或表级锁,默认为页面锁 InnoDB支持行级锁(row-level locking)和表级锁,默认为行级…...

【C++面向对象侯捷】8.栈,堆和内存管理
文章目录 栈,堆stack object的生命周期static local object的生命周期global object的生命周期heap objects 的生命期new:先分配memory,再调用构造函数delete: 先调用析构函数,再释放 memory动态分配所得的内存块,in V…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...