【ShuQiHere】 深入理解队列的实现方式:数组、链表与循环队列的全面解析

🎓 【ShuQiHere】 🌟

在计算机科学中,队列(Queue) 是一种常见的数据结构,它遵循**先进先出(FIFO, First In First Out)**的原则。无论是任务调度、消息队列、或是操作系统中的任务管理,队列都扮演了至关重要的角色。

今天,我们将深入探讨四种常见的队列实现方式,并通过类比和代码示例帮助大家更好地理解每种实现方式的特点。


📖 目录

  1. 队列的基本概念
  2. 数组实现队列
  3. 链表实现队列
  4. 循环队列
  5. 移动元素的队列实现
  6. 总结

🧠 队列的基本概念

队列是一种遵循**先进先出(FIFO, First In First Out)**原则的线性数据结构。这意味着第一个进入队列的元素将是第一个被移除的元素,类似于现实生活中的排队场景。它通常支持两种操作:

  • 入队(Enqueue):将元素添加到队列末尾。
  • 出队(Dequeue):从队列前端移除元素。

接下来,我们将分别探讨四种常见的队列实现方式,并通过代码和类比帮助你更好地理解它们。


📦 数组实现队列(Array Queue) ☕️

数组实现队列(Array Queue) 是最基本的队列实现方式。它通过一个固定大小的数组来存储元素,并使用两个指针来追踪队列的前端(front)和尾端(rear)。

🎨 形象类比:固定排队窗口

想象一下你在一家咖啡店排队,店内有一排固定的座位,每个顾客只能按照顺序入座,依次从第一个座位开始坐。当一个顾客离开后,虽然座位空出来了,但后面的顾客不会前移,新来的顾客也不能占用前面空出来的座位。这就导致空间浪费——这正是数组实现队列的一个典型问题。

🛠 主要操作:

  • enqueue(入队):在队列末端插入新元素,rear 指针向后移动。
  • dequeue(出队):从队列前端移除元素,front 指针向后移动,但前面的空位不能再被利用。

🌟 优点:

  • 数组结构简单,入队和出队操作时间复杂度均为 (O(1))。

⚠️ 缺点:

  • 队列容量固定,无法动态扩展。
  • 前端空位不能被重用,导致空间浪费。

📝 代码示例:

class ArrayQueue:def __init__(self, capacity):self.queue = [None] * capacityself.capacity = capacityself.front = 0self.rear = -1self.size = 0def is_empty(self):return self.size == 0def is_full(self):return self.size == self.capacitydef enqueue(self, item):if self.is_full():print("队列已满,无法入队")returnself.rear += 1self.queue[self.rear] = itemself.size += 1print(f"元素 {item} 已入队。队列状态:{self.queue}")def dequeue(self):if self.is_empty():print("队列为空,无法出队")return Noneitem = self.queue[self.front]self.queue[self.front] = Noneself.front += 1self.size -= 1print(f"元素 {item} 已出队。队列状态:{self.queue}")return item

🚀 小结:

数组实现队列简单高效,但它的固定大小和空间浪费问题使得它在需要频繁入队和出队的场景中并不理想。


🔗 链表实现队列(Linked List Queue) 🏃‍♂️

链表实现队列 是通过链表来动态存储数据,每个节点不仅存储元素,还包含一个指向下一个节点的指针。这种实现方式允许队列根据需要动态增长。

🎨 形象类比:动态排队队伍

想象一条动态的排队队伍,每个顾客都可以自由站在队伍的末尾。即使前面的顾客离开,后面的顾客也会自然向前移动,队伍的长度根据需求不断调整。这种灵活的排队方式正是链表实现队列的特点。

🛠 主要操作:

  • enqueue(入队):在链表末端插入新节点。
  • dequeue(出队):移除链表的头部节点。

🌟 优点:

  • 队列大小不受限制,可以根据需要动态扩展。
  • 没有空间浪费问题。

⚠️ 缺点:

  • 每个节点需要额外的内存来存储指针,增加了内存开销。

📝 代码示例:

class Node:def __init__(self, data):self.data = dataself.next = Noneclass LinkedListQueue:def __init__(self):self.front = Noneself.rear = Noneself.size = 0def is_empty(self):return self.front is Nonedef enqueue(self, item):new_node = Node(item)if self.is_empty():self.front = self.rear = new_nodeelse:self.rear.next = new_nodeself.rear = new_nodeself.size += 1print(f"元素 {item} 已入队。队列当前长度:{self.size}")def dequeue(self):if self.is_empty():print("队列为空,无法出队")return Noneitem = self.front.dataself.front = self.front.nextif self.front is None:self.rear = Noneself.size -= 1print(f"元素 {item} 已出队。队列当前长度:{self.size}")return item

🚀 小结:

链表实现的队列适合需要灵活调整队列大小的场景,避免了数组队列中的空间浪费问题,但额外的指针存储增加了内存开销。


🔄 循环队列(Circular Queue) 🔄

循环队列(Circular Queue) 是一种使用数组实现的队列,但通过取模运算使得数组首尾相连,从而有效利用前端的空位。

🎨 形象类比:环形传送带

想象一个环形传送带,每个顾客都可以在传送带上占据一个位置。当顾客离开时,传送带会继续旋转,新来的顾客可以占据空出来的位置,即使传送带转了一圈,空间仍然可以被重复利用。这种场景类似于循环队列的工作原理。

🛠 主要操作:

  • enqueue(入队):将元素插入队列尾端,rear 通过取模运算实现循环。
  • dequeue(出队):从队列前端移除元素,front 通过取模运算实现循环。

🌟 优点:

  • 可以充分利用数组的空间,不会浪费前端空位。

⚠️ 缺点:

  • 需要处理前端和尾端指针的循环操作,稍微增加了实现复杂性。

📝 代码示例:

class CircularQueue:def __init__(self, capacity):self.queue = [None] * capacityself.capacity = capacityself.front = 0self.rear = -1self.size = 0def is_empty(self):return self.size == 0def is_full(self):return self.size == self.capacitydef enqueue(self, item):if self.is_full():print("队列已满,无法入队")returnself.rear = (self.rear + 1) % self.capacityself.queue[self.rear] = itemself.size += 1print(f"元素 {item} 已入队。队列状态:{self.queue}")def dequeue(self):if self.is_empty():print("队列为空,无法出队")return Noneitem = self.queue[self.front]self.queue[self.front] = Noneself.front = (self.front + 1) % self.capacityself.size -= 1print(f"元素 {item} 已出队。队列状态:{self.queue}")return item

🚀 小结:

循环队列能够有效利用数组中的空位,避免空间浪费,适合需要高效空间利用的场景。然而,由于指针需要循环操作,代码的实现复杂性略有提升。


🚛 移动元素的队列实现(Shift Queue) 🚛

移动元素的队列实现(Shift Queue) 是一种特殊的队列实现方式,每次出队时,所有后面的元素都会向前移动一位。这种方式确保队列总是从数组的第一个位置开始,但其性能会因为频繁的元素移动而变得非常低效。

🎨 形象类比:自动前移的队伍

想象一条队伍,每当有顾客离开时,所有后面的顾客都会自动向前移动一位。这种排队方式虽然保证了队伍的整齐,但每次有人离开时,队伍的整体移动都会带来不小的负担。这就类似于移动元素的队列实现方式。

🛠 主要操作:

  • enqueue(入队):在队列尾端插入新元素。
  • dequeue(出队):移除队列前端的元素,所有剩余元素向前移动。

🌟 优点:

  • 队列始终保持整齐,前端总是从数组的第一个位置开始。

⚠️ 缺点:

  • 每次出队都需要移动剩余元素,导致时间复杂度为 (O(n)),效率低下。

📝 代码示例:

class ShiftQueue:def __init__(self, capacity):self.queue = [None] * capacityself.capacity = capacityself.size = 0def is_empty(self):return self.size == 0def is_full(self):return self.size == self.capacitydef enqueue(self, item):if self.is_full():print("队列已满,无法入队")returnself.queue[self.size] = itemself.size += 1print(f"元素 {item} 已入队。队列状态:{self.queue}")def dequeue(self):if self.is_empty():print("队列为空,无法出队")return Noneitem = self.queue[0]for i in range(1, self.size):self.queue[i - 1] = self.queue[i]self.queue[self.size - 1] = Noneself.size -= 1print(f"元素 {item} 已出队。队列状态:{self.queue}")return item

🚀 小结:

移动元素的队列实现虽然保证了队列的整齐,但由于每次出队都需要移动元素,效率非常低,不适合频繁出队的场景。


🧠 总结

通过本文的介绍,我们详细讨论了四种常见的队列实现方式:

  • 数组实现队列:简单高效,但固定大小和空间浪费是主要问题。
  • 链表实现队列:动态扩展的优势使其适用于不定长队列,但额外的指针存储增加了内存开销。
  • 循环队列:通过取模运算实现了数组空间的循环使用,适合高效空间利用的场景。
  • 移动元素队列:虽然队列始终保持整齐,但频繁移动元素带来的效率问题使其不适合大多数场景。

每种队列实现都有其优缺点,具体选择应根据实际应用场景的需求做出权衡。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

华为全联接大会HUAWEI Connect 2024印象(五):讯飞星火企业级智能体平台

在HC大会上,除了有华为自己的产品,还有很多合作伙伴的产品,今天就简单说一下讯飞星火的企业级智能体平台。讯飞星火此次在HC上有多个展台。我以前是讯飞星火的拥泵,在B站发过视频介绍其API的使用(利用API访问讯飞星火认…

PR视频剪辑工具全指南:开启专业剪辑之旅

pr视频剪辑可以说是视频剪辑里的一把好手,就是如果你想在这方面深耕那还是掌握这个工具的使用比较方便。如果你只是刚入门,那也有不少可以快速帮你剪辑出片的工具。这次我介绍几款我用过的视频剪辑工具,助你开启视频剪辑大门。 1.福昕视频剪…

构建预测睡眠质量模型_相关性分析,多变量分析和聚类分析

数据入口:睡眠质量记录数据集 - Heywhale.com 本数据集目的是探究不同因素是如何影响睡眠质量和整体健康的。 数据说明 字段说明Heart Rate Variability心率变异性:心跳时间间隔的模拟变化Body Temperature体温:以摄氏度为单位的人工生成体…

深度学习(2):梯度下降

文章目录 梯度下降梯度是什么常见梯度下降算法 代码实现批量梯度下降 梯度下降 梯度是什么 类似y ax b这种单变量的函数来说,导数就是它的斜率,这种情况下可以说梯度就是导数。 但在多变量函数中,梯度是一个向量,其分量是各个…

时间序列LSTM实现

这个代码参考了时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)_lstm预测模型-CSDN博客 结合我之前所学的lstm-seq2seq里所学习到的知识对其进行预测 import time import numpy as np import pandas as pd import torch import…

STM32F407之超声波模块使用

#include "sys.h" #include "delay.h" #include "usart.h" #include "includes.h" #include "HC_SR04.h"int main() {OS_ERR err;//错误uart_init(9600);//串口初始化//超声波初始化HC_SR04();//OS初始化 他是第一个运行的函…

Karmada新版本发布,支持联邦应用跨集群滚动升级

摘要:本次升级支持联邦应用跨集群滚动升级,使用户版本发布流程更加灵活可控;透明同事karmadactl 新增了多项运维能力,提供独特的多集群运维体验。 本文分享自华为云社区 《Karmada v1.11 版本发布!新增应用跨集群滚动升…

nfs版本问题导致挂载失败

一、系统环境 环境版本操作系统Linux Mint 22 Wilma内核版本6.8.0-44-genericgcc 版本arm-none-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025uboot 版本2020.01开发板Linux版本5.4.31 二、问题描述 内核通过…

Unity开发绘画板——03.简单的实现绘制功能

从本篇文章开始,将带着大家一起写代码,我不会直接贴出成品代码,而是会把写代码的历程以及遇到的问题、如何解决这些问题都记录在文章里面,当然,同一个问题的解决方案可能会有很多,甚至有更好更高效的方式是…

微信小程序——引入 iconfont 矢量图标,如何使用引用阿里巴巴矢量图标

本文介绍如何在小程序中加入图标,效果如下图: 1、访部iconfont-阿里巴巴矢量图标库 找到需要的图标,然后添加入库 将增加好的图标添加到项目中 2、点击更新生成代码 生成后如下图 3、打开生成的css样式文件 4、在小程序中新建/static/iconfon…

AI大模型助力数据消费,构建数据飞轮科学、高效的体系

随着互联网的技术高速发展,越来越多的应用层出不穷,伴随着数据应用的需求变多,为快速响应业务需求,很多企业在初期没有很好的规划的情况下,存在不同程度的烟囱式的开发模式,这样会导致企业不同业务线的数据…

**CentOS7安装redis**

CentOS7安装redis 首先解压压缩包 redis-7.0.0.tar.gz tar -xvf redis-7.0.0.tar.gz接着进入到redis中 cd redis-7.0.0.tar.gz执行make命令编译 make接着执行安装命令 make install之后编译安装完后 程序都会在/usr/local/bin目录下 这里需要将在redis目录中redis.conf配置…

Kubernetes从零到精通(14-Storage)

存储简介 在Kubernetes中,存储是一个关键的部分,用于持久化应用程序的数据。Kubernetes的存储模型支持多种存储类型,并且能根据应用程序的需求动态地提供存储资源。以下是Kubernetes存储的基本概念和机制。 Kubernetes支持很多类型的卷。Pod可…

【Java面向对象高级一08】继承_使用继承的好处

前言 一、继承是什么? 二、使用继承的好处 总结 前言 继承的学习 一、继承是什么? Java中提供了一个关键字extends,用这个关键字,可以让一个类和另一个类建立起父子关系。extends(中文意思就是继承)。 继承的意思是&#xf…

Redis实战--Redis的数据持久化与搭建Redis主从复制模式和搭建Redis的哨兵模式

Redis作为一个高性能的key-value数据库,广泛应用于缓存、消息队列、排行榜等场景。然而,Redis是基于内存的数据库,这意味着一旦服务器宕机,内存中的数据就会丢失。为了解决这个问题,Redis提供了数据持久化的机制&#…

C语言 | Leetcode C语言题解之第434题字符串中的单词数

题目&#xff1a; 题解&#xff1a; int countSegments(char * s){int count 0; //count用来记录单词个数for(int i0; i < strlen(s); i){ //遍历字符串 if((i 0 || s[i-1] ) && s[i] ! ) //一个…

Python | Leetcode Python题解之第434题字符串中的单词数

题目&#xff1a; 题解&#xff1a; class Solution:def countSegments(self, s):segment_count 0for i in range(len(s)):if (i 0 or s[i - 1] ) and s[i] ! :segment_count 1return segment_count

【计网】从零开始掌握序列化 --- 实现网络计算器项目

​​​请各位保持头脑清醒&#xff0c; ​​​读些好书&#xff0c;做点有用的事&#xff0c; ​​​快快乐乐地生活。 ​​​ --- 斯蒂芬金 《肖申克的救赎》--- 从零开始掌握序列化 1 知识回顾2 服务器框架3 客户端框架4 运行测试 1 知识回顾 前面两篇文章学习中基础知识…

ROS第六梯:ROS+VSCode+C++消息发布和订阅

第一步&#xff1a;创建ROS工作空间&#xff0c;并在工作空间下创建名为srr_pkg的功能包&#xff0c;具体步骤参考第二章。 第二步&#xff1a;在src下创建publisher.cpp作为发布节点代码文件&#xff0c;创建subscriber.cpp作为订阅节点代码文件&#xff1a; 主要步骤是&#…

数字通云平台智慧政务 login 存在登录绕过

0x01 漏洞描述&#xff1a; 数字通云平台智慧政务OA产品是基于云计算、大数据、人工智能等先进技术&#xff0c;为政府部门量身定制的智能化办公系统。该系统旨在提高政府部门的办公效率、协同能力和信息资源共享水平&#xff0c;推动电子政务向更高层次发展。 数字通云平台 智…