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

队列

概念

队列是一种特殊的线性表,特殊之处在于它遵循先入先出(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,一经查实,立即删除!

相关文章

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

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

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

来源&#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、大数据-行业…

剑指 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篇文章。每篇文章…

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;…

❤「和平精英」被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;所以以后尽力多做分享&#…

深度 | 激光雷达独角兽Quanergy的危急时刻

来源&#xff1a;网易智能编译摘要&#xff1a;全球知名的激光雷达制造商 Quanergy 最近陷入了麻烦之中。早在2014年&#xff0c;Quanergy公司就发现自己正身处于一场对自动驾驶汽车突如其来的狂热之中。Quanergy公司制造了激光雷达技术&#xff0c;这是一种将激光反射到物体上…

❤ 就这?TypeScript其实并不难!(建议收藏)❤

&#x1f388; 作者&#xff1a;不吃西红柿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;、蓝桥签约作者、Python领域优质创作者、信息技术智库公众号创建者✌。技术交流、面试刷题尽管关注咨询我。 热门专栏推荐&#xff1a; &#x1f947; 知识集锦专栏&…

EntityModelStudio系列教程2--静态建模之实体模型设计

在EMStudio中静态建模的概念和内容是来自于UML标准的&#xff0c;所以EMStudio提供的静态建模的设计能力是完全可以满足开发者的设计要求的。但是与UML标准比较&#xff0c;EMStudio中的静态建模还存在两个不同的特色&#xff1a; 1. 类与实体的概念是一致的 也就是说&#xff…

前沿科技山雨欲来,四大领域存创新机会

来源&#xff1a;北极光创投摘要&#xff1a;最近&#xff0c;北极光创投董事总经理杨磊&#xff0c;发表了《前沿科技山雨欲来》的主题演讲&#xff0c;他认为目前全球正处于前沿科技爆发前夜&#xff0c;他看好计算构架变革、移动终端、机器人、生物科技与IT融合四大领域的创…

工业机器人发展现状:硬件制造大同小异,视觉感知绘新蓝图

来源 &#xff1a;亿欧摘要&#xff1a;8月15日-8月19日&#xff0c;在北京亦庄国际会展中心举办了为期五天的2018世界机器人大会。小编认为&#xff0c;国内工业机器人的总体水平在未来长期时间将处于稳定上升区&#xff0c;而两极分化趋势愈显。8月15日-8月19日&#xff0c;在…

[C# 网络编程系列]专题七:UDP编程补充——UDP广播程序的实现

本专题主要介绍下如何实现UDP广播的程序&#xff0c;下面就直接介绍实现过程和代码以及运行的结果。 一、程序实现 UDP广播程序的实现代码&#xff1a; using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.W…

我们离得开美国的软件和硬件吗?

来源&#xff1a;网易科技摘要&#xff1a;据报道&#xff0c;你当然可以淘汰很多美国产品&#xff0c;但你可能也会因此放弃许多令人惊叹的功能。据报道&#xff0c;你当然可以淘汰很多美国产品&#xff0c;但你可能也会因此放弃许多令人惊叹的功能。例如&#xff0c;超过10亿…

❤️❤️❤️【资料免费领取】简历模板、职场PPT模板、硬核学习资料+PDF资料(Java、Python、大数据、机器学习)❤️❤️❤️

&#x1f345;【领取方法】 长按识别二维码&#xff0c;回复【资料】领取 目录 1、100套小编购买的简历模板&#xff08;部分截图&#xff09; 2、1000套精品PPT模板&#xff08;部分截图&#xff09; 3、大数据-学习资料&#xff08;1.3G 硬核PDF&#xff0c;官方指南&…