1.了解队列的存储方式

1.(1)数组形式存储

2. (2)链式存储(链表形式)

(1)数组形式的存储方式为连续存储(顺序存储),也就是说该队列的地址是连续的。我们看下图:

该存储方式的头指针与尾指针在没有元素时同时指向下标为-1的位置(注意,只是表现形式).当存储元素之后,队头指针指向第一个元素,队尾指针指向最后一个元素的下一位.如下图:

Ps:纯手工画的不好.hh

唉?你说那么多是不是优先队列就是这么做的呢?别急,别急,我只是给小白科普一下队列的存储方式,不至于那么懵逼。顺序存储的队列一般用作少量元素的处理。(有一种顺序存储队列的特殊情况,循环队列。这个在一些应用场景下比单链表存储方式更高效!!这篇文章效果好下波就更新循环队列)。否则效率虽然不低,但是也不高啊。顺序存储留一个印象给你们,接下里我们讲第二个存储方式。

(2)链式存储队列(链表形式),这个就是我们这次要说的重头戏,一般高效的数据结构都是采用链式储存的(有没有没学好链表的同学?),这次我们的优先队列也不例外。除此之外我们的HTTP反向代理服务器Nginx里面的文件缓存处理方式也是使用链式储存结构的(但是稍稍和我今天说的不一样,那个使用了Linux内核链表常用形式)。好了好了,扯太多了。言归正传今天的高逼格应用-优先队列。我们先让小萌新们看看图:

这就是链式存储的队列(有没有懵逼呢,哈哈)。和顺序存储的方式相差不大,队头指针一如既往指向队头,但是队尾指针不是指向下一位了啊。直接指向最后一个结点(其实就是保存了最后一个结点的地址,我怕你们基础太差听不懂还是解释一下吧)。这里还要补充两个规则。如果一开始没有结点。那么队头指针和队尾指针同时指向NULL(xxx->front=NULL;).

另一个我相信大家也听说过,不过没听说过也没关系。就是元素只能从队尾进队头出(就像排队一样,不然为什么叫队列呢?)。好了,到这里我相信大家应该对队列一知半解了。好,我们开始发车。(我估计有人已经等不及了,当然了。肯定还有很多新手不是很了解,但是没关系,你们只需要看我下面的操作就行了。以后会有机会详细讲解其他数据结构)。

2. 优先队列和一般链式存储队列的差别

为了防止大家懵逼,我们一步一步来。先看看普通链式存储队列的形式。废话不多说,直接上代码:

很明显,这里面有我们刚才说的数据和结点。另一个结构体就是我们的队头指针和队尾指针了,这就是普通链式存储队列的结构(这个时候就有同学要问了,你这个怎么还有个length是什么啊?哈哈,我之前忘记说了,队列是有长度的,很多时候就是这样,当你深入理解一个概念的时候是不需要死记硬背的。需要的时候就会想起,这个长度补充一下,就是当前队列长度,用来判断是否满队,是否队空)。

那我们来看看心心念念的优先队列结构是怎么样的呢?我们先来看一张内存图:

我相信大家已经看出来了,优先队列和普通链式存储的队列区别在于多了一个优先级(这个要怎么解释呢?我想了一下,拿现实的东西来类比一下吧。你去银行排了很久的队,银行不允许插队,从队头办业务,队尾排队(队列特性),但是他们的VIP可以优先办理,也就是说,队头和队尾不受影响,窗口优先处理VIP的业务)。说到这里大家都应该有一个感性的认识了。那我们接着往下看看优先队列的数据结构用代码写是什么样的呢。来,请看下图:

我们可以看到,这里面多了一个优先级priority。除此之外没有任何变化(优先级由程序员本身决定,我这里为了贴合实际,采用数字越大优先级越高),停停停,你的MAX_SIZES是干什么的?哈哈,为了照顾一下小萌新,我略微说一下,这个就是队列的最大长度,结点数不能超过这个数(类比一些现实生活特殊情况的排队)。

那么结构上面的差别我们讲完了,算法上面的差别有没有呢?那肯定有啊,不然我写这个博客干什么(hh),但是差别只存在一个地方,我想已经有人猜到了,那就是出队的情况。优先级越高的,出队越快。别急,我给大家讲一个例子,这个例子说明了除了资本家善用优先队列还有什么情况可以使用,请看下图:

现在已经有了一定的理解了吧,这就是为什么出队的算法实现会不同的原因。好了,普通链式队列和优先队列的差别已经介绍完了,接下来是他的算法实现。

3.优先队列的算法实现

好了,终于到我们激动人心的环节了。算法实现!我相信肯定有人等不及了,(我知道你很急,但是你先别急)。接下来的内容可能有点难度,系好安全带,我要发车了。首先,为了节省大家的时间,我默认大家会普通链式队列了(可能不会,但是没关系)。好了,接下来看我操作。先给大家看看我们要做的流程,如图:

1.初始化队列(上图是不是看的清楚些?):

首先,我们先用一个二级指针初始化LinkQNode类型结构体变量(队头指针和队尾指针),这里会有同学问了,你怎么用二级指针?是不是闲着没事找事,我用一级指针行不行?或许你会有这样的疑问,但是我先告诉你答案:不行(至于为什么,这个又涉及到指针的中级应用,我的博客只写了初级应用,可惜了),你可以去试一下,当然了,改变我函数内部的写法或许可以。好了,言归正传。我们给这个指针申请一块内存(我知道肯定有人不懂,不要急。以后我可能会讲解,这个的东西讲三天三夜也很难讲完啊)。然后就是老鸟程序员经常使用的防御性编程(如果分配内存失败则返回假,具体处理结果由主函数内部实现)。然后我们将队头指针和队尾指针都指向NULL。队列长队置位0。执行完以后返回真。

2.判断队列是否为满(和普通链式存储队列同理):

这个就很简单了。直接对比当前队列长度和最大队列长度就行了。没到就返回真,否则返回假。那么这个有什么用呢?别急,等等插入元素的时候你就知道了。

3.插入元素(老调重弹):

怎么插入呢(~v~)? 首先我们先判断队列是否为满,你看,这不就显示出了上一个函数的作用了吗(这里要提一下,在实际开发中,常用功能最好写成一个函数)。(还有很重要的一点,我上面这个函数的代码风格有问题,同学们不要模仿哦。我是为了截图截完才改成这样的。心好累)队列满了返回假,为真继续执行,先申请一块结点的内存。注意,这里面有一个特殊情况。就是队列为空时,队头指针和队尾指针都是空的,要特殊处理。如果长队为0,则代表队列为空。将我们的数据装载进入结点。(由于我懒得设置优先级了,直接拿数据当优先级来用,达到演示目的)。然后将队头指针指向该结点,对尾指针也指向该结点,将该结点的指针域置空,最后队列长度++。然后返回真(其实这里面我可以做的更好的,但是今天累了,不打算优化了。)如果不是空队列,前面的步骤和上面差不多,但是尾结点的指针域保存该结点的地址,然后队尾指针指向该结点,队列长度++,然后返回真。(我眼睛有点累了)。这样我们入队就完成了。

4.打印队列元素(都一样都一样):

 首先判断队列是否为空(老防御编程了),然后定义一个临时指针指向该队头内容(第一个结点的地址),然后定义一个整形i=0,用来逐一遍历队列。进入循环,当p不为空的时候就一直循环(这是不可能的)。打印完以后就把下一个结点的地址赋值给p。达到遍历效果。

5.出队(重头戏来了,我好累了)

由于代码较长我就不上图了,直接上代码。

bool deQNode(LinkQNode* queue)

{

if (!queue)

{

cout << "队列非法" << endl;

return false;

}

if (queue->length < 1)

{

return false;

}

QNode** twolast = NULL;

QNode* last = NULL;

QNode* tmp = NULL;

QNode* preave = NULL;

twolast = &(queue->foront);

last = queue->foront;

tmp = last->next;

while (tmp)

{

preave = last;

if ((*twolast)->priority < tmp->priority)

{

twolast = &(last->next);

}

last = tmp;

tmp = tmp->next;

}

if (queue->length == 1)

{

delete queue->foront;

queue->foront = NULL;

queue->rear = NULL;

queue->length--;

return true;

}

else if ((*twolast) == queue->rear)

{

delete queue->rear;

queue->rear = preave;

queue->rear->next = NULL;

queue->length--;

return true;

}

*twolast = (*twolast)->next;

delete tmp;

queue->length--;

return true;

}

来了,压轴戏。这里面出队的核心思想就是比较优先级,如果大家优先级一样那就是普通链式存储队列。但是大部分情况总是有VIP的。来,一开始就是防御性编程。这个我就不说了。然后我们使用二级指针来处理这个队列。你怎么老是用二级指针?停停停,这里面如果不用二级指针的话就得用两个一级指针。你也不想用两个指针吧。为什么呢?这就是核心了,使用二级指针其实是保存了当前优先级最高结点的上一个结点的指针域的地址。什么?你没听懂?我也猜得到你没听懂。但是呢,我不打算深入讲解这部分,因为有点麻烦。我简单说说思想,二级指针在删除优先级最高结点的时候,本身是不受影响的。所以可以少用一个指针。这个应该能听懂一点吧。还有,出队的时候有两个特殊情况,什么情况呢?这两个特殊情况就是,万一删掉最后一个结点(只有一个结点的那种)。就要特殊处理,如果删掉的是最后一个呢?那也得特殊处理。具体看我的代码吧。毕竟码字确实不容易啊(学习太多东西都是连续的了,一个队列里面的知识不仅仅是队列)。好了,我们来看看运行结果如何,看下图:

 我们可以看到,成功删除掉了优先级最高的元素。实现成功!

其实里面有很多内容都需要长久的学习,才能深入理解。我希望大家都能学有所得,写的不好多多关照。

我是程序员玉无涯,关注我。带你变成高级程序员。

想深入学习的可以私信我哦

数据结构队列之企业级应用--优先队列相关推荐

  1. java 数据结构_Java版-数据结构-队列(数组队列)

    前言 看过笔者前两篇介绍的 Java版数据结构 数组和 栈的盆友,都给予了笔者一致的好评,在这里笔者感谢大家的认可!!! 由于本章介绍的数据结构是 队列,在队列的实现上会基于前面写的 动态数组来实现, ...

  2. 从队列、二叉树到优先队列

    优先队列(priority queue),也是一种重要的缓存结构.从原理上说,这种线性结构与二叉树没有直接关系.但是基于对一类二叉树的认识,可以做出优先队列的一种高效实现. 注意,队列和优先队列的选择 ...

  3. java循环队列_Java版-数据结构-队列(循环队列)

    前情回顾 在上一篇,笔者给大家介绍了数组队列,并且在文末提出了数组队列实现上的劣势,以及带来的性能问题(因为数组队列,在出队的时候,我们往往要将数组中的元素往前挪动一个位置,这个动作的时间复杂度O(n ...

  4. 数据结构——队列的C++实现

    数据结构--队列的C++实现 \qquad队列的创建.判断是否为空或者满.入队和出队操作的C++实现. #include<iostream> using namespace std;//1 ...

  5. java 数据队列_Java 数据结构 - 队列

    Java 数据结构 - 队列 我们今天要讲的数据结构是队列,比如 Java 线程池任务就是队列实现的. 1. 什么是队列 和栈一样,队列也是一种操作受限的线性结构.使用队列时,在一端插入元素,而在另一 ...

  6. 数据结构队列代码_代码简介:队列数据结构如何工作

    数据结构队列代码 Here are three stories we published this week that are worth your time: 这是我们本周发布的三个值得您关注的故事 ...

  7. 第七周--数据结构--队列数组

     /*    *第七周--数据结构--队列数组     *Copyright (c) 2015 烟台大学计算机与控制工程学院    *All right reserved.    *文件名称:li ...

  8. 数据结构-队列和栈有什么区别

    数据结构-队列和栈有什么区别 1:队列和栈是两种不同的数据结构.它们有以下区别: (1)操作的名称不同.队列的插入称为入队,队列的删除称为出队.栈的插入称为进栈,栈的删除称为出栈. (2)可操作的方式 ...

  9. 数据结构——队列的C语言代码实现

    系列文章目录 数据结构--顺序表的C语言代码实现 数据结构--八种链表的C语言代码实现 数据结构--栈的C语言代码实现 数据结构--队列的C语言代码实现 数据结构--堆的C语言代码实现 文章目录 系列 ...

最新文章

  1. 用SecureCRT在linux系统下载文件
  2. linux shell curl 超时与重试
  3. django基础知识~RBAC实验部分代码记录
  4. [转]MyBatis中resultType与resultMap区别
  5. 机器学习之决策树的原理及sklearn实现
  6. Leetcode-MySQL-180. 连续出现的数字
  7. 安装nginx、drizzle和lua
  8. 【java】java 关键字: synchronized详解
  9. PHP代码重用与函数编写
  10. 65个面试常见问题技巧回答,你知道吗
  11. 强大web打印控件下载 - 2019年最新支持所有浏览器-楚琳打印
  12. 韩立刚老师 《计算机网络》视频课程目录
  13. Java8日期时间API
  14. 如何用ffmpeg合并音频和视频?
  15. 细胞工程-6-原生质体分离核体细胞杂交
  16. Form(窗体)的FormBorderStyle属性的不同效果
  17. 华为云桌面---cloudclient安装使用
  18. 验证input和textarea的输入是否有效,也就是不为空,也不都是空格
  19. 关于腾讯云服务器使用FTP详细配置教程
  20. C语言里文字颜色色和背景颜色设置

热门文章

  1. 荣耀20特别版 鸿蒙,【首发】鸿蒙OS华为首款特别版荣耀20全球发布,3999元你会支持吗...
  2. 相位展开(phase unwrapping)
  3. Python基础,猜成语小游戏
  4. 杰森xbl_每日新闻摘要:Google杀死了230万个不良广告,微软宣布XBL游戏栈等等
  5. Java工程师是做什么的?学习java能干什么?
  6. 人脸识别中的活体检测算法综述
  7. 基于CAN的网络管理NM(network management)
  8. 分享一个简单好用的快递查询、物流管理软件
  9. canvas内的字体实现阴影效果
  10. fl studio mobile安卓,ios下载