数据结构 - 队列(图解+源码)

队列

概念

队列是一种特殊的线性表,特殊之处在于它遵循先入先出(FIFO)原则,只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

队列区分

根据队列的存储方式不同可以分为顺序存储(数组)和链式存储(链表),根据链表的形式又可以分为顺队列与循环队列

顺序队列

顺序队列顾名思义就是一条路走到黑,front指向队头,rear指向队尾,通过这两个下标对队列进行操作,如下图所示:
在这里插入图片描述
每次在队尾插入一个元素是,rear增1;每次在队头删除一个元素时,front增1。随着插入和删除操作的进行,队列元素的个数不断变化,队列所占的存储空间也在为队列结构所分配的连续空间中移动。当front=rear时,队列中没有任何元素,称为空队列。当rear增加到指向分配的连续空间之外时,队列无法再插入新元素。

顺序队列实现

package queueimport "fmt"type Queue struct {maxSize intfront   int // 队列头节点默认为节点的前一个rear    int // 队列尾节点queue   []int
}func NewQueue(maxSize int) *Queue {q := new(Queue)q.maxSize = maxSizeq.queue = make([]int, 0,maxSize)q.front = -1q.rear = -1return q
}// Add 向队列中添加元素
func (q *Queue) Add (val int)  {if q.isFull() {fmt.Println("当前队列已满!")return}q.queue = append(q.queue, val)q.rear++return
}// Get 从队列中获取元素
func (q *Queue) Get () int {if q.isEmpty() {return -1}q.front++return q.queue[q.front]
}// Show 查看整个队列元素
func (q *Queue) Show() []int{if q.isEmpty() {return []int{}}queues := make([]int, 0,q.maxSize)for i := q.front +1; i <= q.rear; i++{queues = append(queues, q.queue[i])}return queues
}// 队列是否满了?
func (q *Queue) isFull() bool {return q.rear == q.maxSize-1
}// 队列是否为空
func (q *Queue) isEmpty() bool {return q.rear == q.front
}
``
```bash
package mainimport ("Queue/queue""fmt"
)func main()  {fmt.Println("add 添加元素")fmt.Println("get 获取元素")fmt.Println("show 查看所有元素")fmt.Println("exit 退出程序")fmt.Printf("请输入队列长度:")var queueLen intfmt.Scanln(&queueLen)q := queue.NewQueue(queueLen)fmt.Println("队列容积:", queueLen)for {var point stringfmt.Scanln(&point)switch point {case "add":fmt.Printf("输入添加元素:")var val int_, err := fmt.Scanln(&val)if err != nil {continue}q.Add(val)case "get":getVal := q.Get()if getVal == -1{fmt.Println("队列为空,请先添加元素^_^")}else{fmt.Println("获取元素:", getVal)}case "show":vals := q.Show()if len(vals) == 0 {fmt.Println("队列为空,请先添加元素^_^")}else{fmt.Println("队列全部元素为:", vals)}case "exit":fmt.Println("bey~~")returndefault :fmt.Println("输入有误,请重新输入-_-!!")}}
}

运行效果
在这里插入图片描述

顺序队列中的溢出现象:

(1) "下溢"现象:当队列为空时,做出队运算产生的溢出现象。“下溢”是正常现象,常用作程序控制转移的条件。
(2)"真上溢"现象:当队列满时,做进栈运算产生空间溢出的现象。“真上溢”是一种出错状态,应设法避免。
(3)"假上溢"现象:由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。当队列中实际的元素个数远远小于向量空间的规模时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。该现象称为"假上溢"现象。

可以发现,当rear增加到指向分配的连续空间之外时,队列无法再插入新元素,但这时往往还有大量可用空间未被占用,这些空间是已经出队的队列元素曾经占用过得存储单元。既然这个问题这么明显,肯定会有一个方案去解决。

循环队列

像前面说的,顺序队列很容易就会造成空间的浪费,为了使队列空间能重复使用,需要对顺序队列的使用方法稍加改进:

  1. 无论插入或删除,一旦rear指针增1或front指针增1 时超出了所分配的队列空间,就让它指向这片连续空间的起始位置。
  2. 自己真从MaxSize-1增1变到0,可用取余运算rear%MaxSize和front%MaxSize来实现。
    在这里插入图片描述

这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用,用这种方法管理的队列也就称为循环队列。除了一些简单应用之外,真正实用的队列是循环队列。
在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,也有front=rear。为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件时front=rear,而队列判满的条件时front=(rear+1)%MaxSize。
循环的队列的状态如图所示:
在这里插入图片描述

循环队列实现

package circleQueueimport "fmt"type CircleQueue struct {front   int //头节点下标rear    int //尾节点下标maxSize int //队列容积queue   []int
}func NewCircleQueue(maxSize int) *CircleQueue {q := new(CircleQueue)q.maxSize = maxSize + 1 // 预留一个空位置做判断q.front = 0q.rear = 0q.queue = make([]int, q.maxSize)return q
}// Add 向队列中添加元素
func (q *CircleQueue) Add(val int) {if q.isFull() {fmt.Println("当前队列已满!")return}q.queue[q.rear] = valq.rear = (q.rear + 1) % q.maxSizereturn
}// Get 从队列中获取元素
func (q *CircleQueue) Get() int {if q.isEmpty() {return -1}defer func() {q.front = (q.front + 1) % q.maxSize}()return q.queue[q.front]
}// Show 查看整个队列元素
func (q *CircleQueue) Show() []int {if q.isEmpty() {return []int{}}// rear = 1   front = 3  1+4-3// rear = 3   front = 1  3+4-1queues := make([]int, 0, q.maxSize)for i := q.front; i < q.front + q.queueSize(); i++ {queues = append(queues, q.queue[i % q.maxSize])}return queues
}// 队列是否满了?
func (q *CircleQueue) isFull() bool {return (q.rear+1)%q.maxSize == q.front
}// 队列是否为空
func (q *CircleQueue) isEmpty() bool {return q.rear == q.front
}// 获取队列元素个数
func (q *CircleQueue) queueSize() int {return (q.rear + q.maxSize - q.front) % q.maxSize
}
package mainimport ("Queue/circleQueue""fmt"
)func main()  {fmt.Println("add 添加元素")fmt.Println("get 获取元素")fmt.Println("show 查看所有元素")fmt.Println("exit 退出程序")fmt.Printf("请输入队列长度:")var queueLen intfmt.Scanln(&queueLen)q := circleQueue.NewCircleQueue(queueLen)fmt.Println("队列容积:", queueLen)for {var point stringfmt.Scanln(&point)switch point {case "add":fmt.Printf("输入添加元素:")var val int_, err := fmt.Scanln(&val)if err != nil {continue}q.Add(val)case "get":getVal := q.Get()if getVal == -1{fmt.Println("队列为空,请先添加元素^_^")}else{fmt.Println("获取元素:", getVal)}case "show":vals := q.Show()if len(vals) == 0 {fmt.Println("队列为空,请先添加元素^_^")}else{fmt.Println("队列全部元素为:", vals)}case "exit":fmt.Println("bey~~")returndefault :fmt.Println("输入有误,请重新输入-_-!!")}}}

运行效果
在这里插入图片描述

由于最近在学习go语言,所以就用golang实现了^_^

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

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

相关文章

测试人员容易遗漏一些隐藏的缺陷

通常软件测试会暴露软件中的缺陷&#xff0c;经过修正后可以保证软件系统的功能满足需求并正确运行。但是&#xff0c;在系统测试和确认测试中&#xff0c;测试人员容易遗漏一些隐藏的缺陷。众所周知&#xff0c;软件测试不可能发现所有的缺陷&#xff0c;而软件开发周期各个阶…

学界 | 清华AMiner团队发布53页计算机图形学研究报告

来源&#xff1a;AI科技评论摘要&#xff1a;清华 AMiner 团队近日发布新一期研究报告——《计算机图形学研究报告》&#xff0c;报告全文共 53 页&#xff0c;从概念、技术、人才、会议、应用及相应趋势详细介绍了计算机图形学的相关内容。报告内容速览概述篇&#xff1a;计算…

『面试知识集锦100篇』2.linux篇丨shell基础命令全集,我奶奶的速查手册!!

目录 第一部分:基础知识 一、Linux 文件基本属性 二、Linux 磁盘管理 2.1 df命令 2.2 du命令 2.3 磁盘检验

❤『面试知识集锦100篇』3.mysql篇丨mysql基础知识和面试真题,看完不收藏算我输!!

作者:不吃西红柿 简介:CSDN博客专家、蓝桥签约作者、大数据&Python领域优质创作者。 谢谢那些曾经击倒我的人, 躺着可真TM舒服。 目录 一、知识体系 1、关系型数据库术语 2、事务的基本要素(ACID)

Ant脚本介绍

1、 Ant简介&#xff1a;这里引用Ant帮助文档中对Ant的介绍&#xff1a; Apache Ant是一个基于Java的构建工具。从理论上讲&#xff0c;也是一种类似于Make的工具&#xff0c;只是去除了Make工具的缺点。 既然已经有了make, gnumake, nmake, jam以及其他的构件工具&a…

爱犯错的智能体 – 视觉篇(五):火星人脸的阴影

来源&#xff1a;张军平科学网博客摘要&#xff1a;人类对外星文明的寻找和痴迷自古就有记载。所以&#xff0c;每每看到拍摄于外星球的照片&#xff0c;必然会情绪激动&#xff0c;试图从中获取存在外星人的蛛丝马迹。一、火星人脸人类对外星文明的寻找和痴迷自古就有记载。所…

链表简单实现(增删查改)

链表 关于链表的原理已经有一篇链表文章写的很详细了&#xff0c;这篇文章主要侧重于代码的实现&#xff0c;主要使用go实现。 单链表实现 package Listtype listNode struct {val intnext *listNode }func newNode(val int) *listNode {node : new(listNode)node.val val…

今天不发技术文,发点粉丝福利

一、资料 1、100套小编购买的简历模板&#xff08;部分截图&#xff09; 2、1000套精品PPT模板&#xff08;部分截图&#xff09; 3、大数据-学习资料&#xff08;1.3G 硬核PDF&#xff0c;官方指南&#xff09; 4、python学习全集 5、Java基础、高级和面试资料 6、大数据-行业…

android Context

讲解Context的一篇不错的文章http://www.cppblog.com/life02/archive/2012/03/19/168328.aspx 调用service时需要一个Context实例&#xff01; 1 2 3 4 public void startWifi(Context context) { WifiManager wifiManager (WifiManager)context.getSystemServic…

剑指 Offer 35. 复杂链表的复制(哈希/衍生拆分图解)

题目描述 请实现 copyRandomList 函数&#xff0c;复制一个复杂链表。在复杂链表中&#xff0c;每个节点除了有一个 next 指针指向下一个节点&#xff0c;还有一个 random 指针指向链表中的任意节点或者 null。 题目分析 题中每个节点新增了 random 指针&#xff0c;指向链表…

自动驾驶技术发展的5个阶段和现状

来源&#xff1a;智车科技摘要&#xff1a;自动驾驶的级别从L1到L5&#xff08;SAE&#xff09;&#xff0c;清晰而直观&#xff0c;是大家讨论自动驾驶行业的一个基准。但是&#xff0c;它也很容易误导人。让人以为自动驾驶的技术会一级一级获得突破&#xff0c;最终迎来一辆L…

❤『知识集锦』一文搞懂mysql索引!!(建议收藏)

作者&#xff1a;不吃西红柿 简介&#xff1a;CSDN博客专家、蓝桥签约作者、大数据领域优质创作者。 以我的资历和文凭&#xff0c;将来这个城市的大街&#xff0c;都归我扫。 【系列课程介绍】 『面试知识集锦』系列课程包括以下20个系列&#xff0c;超过100篇文章。每篇文章…

新来报道

刚刚进入博客园&#xff0c;希望自己在技术上更上一层楼&#xff0c;加油。 给自己点鼓励.一切问题都是可以解决的。遇到问题不要后退&#xff0c;要努力&#xff0c;坚持去解决。坚持学习&#xff0c;坚持写博客&#xff0c;从基础写起。 算来算去&#xff0c;自己也工作几年了…

AI芯片的过去、现在与未来

来源&#xff1a;华尔街见闻摘要&#xff1a;AI芯片似乎没能表现得比人类更智能&#xff0c;但它们的学习能力很强&#xff0c;未来可以变得更聪明。算法和芯片系统的设计都可以进步&#xff0c;这需要AI芯片具备更高级的记忆系统和连接机制&#xff0c;以及承载深度学习数据流…

链表(图文详解)

链表的概念 链表是一种物理存储结构上非连续&#xff0c;非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。   链表的结构是多式多样的&#xff0c;当时通常用的也就是两种&#xff1a;   无头单向非循环列表&#xff1a;结构简单&…

sql join中on条件后接and和where

目录 场景1&#xff1a;left join on a.xx b.xx and a.xx2 aa 场景2&#xff1a;left join on a.xx b.xx and b.xx2 aa 场景3&#xff1a;left join on a.xx b.xx where b.xx2 aa 场景4&#xff1a;inner join on a.xx b.xx where a.xx2 aa 场景5&#xff1a;…

最近学gvim,mark低先

1. vim基本用法&#xff1a;模式&#xff0c;光标移动&#xff0c;查找替换&#xff0c;复制粘贴删除 1.1 帮助 :help :help command 1.2 模式切换 命令模式 Esc, Ctrl-c, 配合光标移动可用Alt-h,Alt-j,Alt-k,Alt-l 编辑模式 i 在当前位置编辑 , a在当前位置后面…

❤「和平精英」被python爬虫了?看看你最适合什么配件!❤

作者简介&#xff1a;不吃西红柿&#xff0c;CSDN博客专家、蓝桥签约作者。 困难像弹簧&#xff0c;你弱它就强&#xff0c;你强它更强。 求点赞、求关注 写作目的&#xff1a; 1、练习爬虫技术&#xff1b; 2、深入了解和平精英枪械属性&#xff0c;提高吃鸡概率。 一、爬前…

(相当全面)node.js 初体验

转载自&#xff1a;http://www.cnblogs.com/Darren_code/archive/2011/10/31/nodejs.html 最近写的文章收到许多朋友的反馈&#xff0c;感谢大家的支持和建议&#xff0c;让我对坚持写博客充满热情&#xff0c;一个月一篇文章确实有点少&#xff0c;所以以后尽力多做分享&#…

创作表情包(备用)

&#x1f476;&#x1f9d2;&#x1f466;&#x1f467;&#x1f9d1;&#x1f471;&#x1f468;&#x1f9d4;&#x1f468;‍&#x1f9b0;&#x1f468;‍&#x1f9b1;&#x1f468;‍&#x1f9b3;&#x1f468;‍&#x1f9b2;&#x1f469;&#x1f469;‍&#x1f9b0…