什么是堆栈和队列?如何实现它们?
堆栈(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…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...