1、概述php
队列是种线性集合,其元素从一端加入,从另外一端删除;注:队列是按照先进先出的方式处理的。从队列中删除元素的次序,与放置元素的次序是同样的。html
(1)方法:前端
操做 | 描述 |
---|---|
enqueue | 向队列末端添加一个元素 |
dequeue | 从队列前段删除一个元素 |
first | 考察队列前端的那个元素 |
isempty | 断定队列是否为空 |
size | 肯定队列的元素数目 |
(2)过程java
(1)队列是一种可存储重复编码密钥的便利集合。git
(2)一般用表示排队的队列来实现模拟。web
2、用链表实现队列编程
(1)那两个分别指向链表首元素、链表末元素的引用方便队列的链表实现。数组
(2)为了从链表的末端出列,必须把一个临时变量设置为指向链表末端的元素。数据结构
(1)enqueue操做要求将新元素放到链表末端。架构
(2)注:新结点的next引用无需显示的进行设置。
(1)enqueue和dequeue操做做用于队列的对立端。
3、用数组实现队列
(1)因为队列操做会修改集合的两端,所以将一端固定于索引0处要求移动元素。
(2)非环形数组实现的元素移位,将产生O(n)的复杂度。
(3)把数组当作环形的,能够出去在队列的数组实现中把元素移位的须要。
(1)概述:简单来说就是若是数组的最后一个索引后面跟的是第一个索引,就可用做环形数组。
(2)注:当添加和删除元素时,不须要移动哪一个元素,可是必定要当心维护front和rear的值。
(1)首先,对于只有一端的队列而言,符合的应当是先进先出的原则,因此最早进入的就应当是最早出去的元素,在进入多个元素之后,这一个先进入的元素就会变成一个队列的队尾,因此在书中有这样一句话:
“为了从链表的末端出列,必须把一个临时变量设置为指向链表末端的元素,而后把tail指针设置为指向当前末端以前的结点。”
因此对于队尾来说,有这样一个rear的结点进行“管理”,防止元素丢失。
(2)而对于首来说,更是重要,它须要去肯定每个元素的位置,防止整个队列元素的丢失。因此下图的展现很可以体现队列的这样一种不一样于链表的结构。
简单表达就是头结点其实至关于队列第一个元素所在结点的前一个结点,经过其来肯定整个队列内部元素的位置
(1)在咱们数组的实现方式中,用两个int型变量用于记录队头和队尾的索引。
图一:
(2)一个队列的初始状态,head和tail都指向初始位置(索引为0处)。head永远指向该队列的队头元素,tail则指向该队列最后一个元素的下一位置,当有入队操做时:
图2:
图3:
(3)当有出队操做时:
图4:
(4)当遇到出队操做时,head会移向下一元素位置。固然,对于这种方式入队和出队,队空的判断条件显然是head=tail,队满的判断条件是tail=array.length(数组最后一个位置的下一位置)。显然,这种结构最致命的缺陷就是,tail只知道向后移动,一旦到达数组边界就认为队满,可是队列可能时刻在出队,也就是前面元素都出队了,tail也不知道。例如:
图5:
(5)此时tail判断队满,咱们暂时认为资源利用是能够接受的,可是若是接下来不断发生出队操做:
图6:
(6)此时tail依然经过判断,认为队满,不能入队,这时数组的利用率咱们是不能接受的,这样浪费很大。因此,咱们引入循环队列,tail能够经过mode数组的长度实现回归初始位置,下面咱们具体来看一下。
按照咱们的想法,一旦tail到达数组边界,那么能够经过与数组长度取模返回初始位置,这种状况下判断队满的条件为tail=head
图7:
(7)此时tail的值为8,取模数组长度8获得0,发现head=tail,此时认为队列满员。这是合理的,可是咱们忽略了一个重要的点,判断队空的条件也是head=tail,那么该怎么区分是队空仍是队满呢?解决办法是,空出队列中一个位置,若是(tail+1)%array.length=head,咱们就认为队满,下面说明其合理性。
上面遇到的问题是,tail指向了队尾的后一个位置,也就是新元素将要被插入的位置,若是该位置和head相等了,那么必然说明当前状态已经不能容纳一个元素入队(间接的说明队满)。由于这种状况是和队空的判断条件是同样的,因此咱们选择舍弃一个节点位置,tail指向下一个元素的位置,咱们使用tail+1判断下一个元素插入以后,是否还能再加入一个元素,若是不能了说明队列满,不能容纳当前元素入队(其实还剩下一个空位置),看图:
图8:
(8)tail经过取模,回归到初始位置,咱们判断tail+1是否等于head,若是等于说明队满,不容许入队操做,固然这是牺牲了一个节点位置来实现和判断队空的条件进行区分。上述文字基本完成了队循环队列的理论介绍,下面咱们看在Java中对该数据结构的具体实现是怎样的。
问题1:最近在编写代码的过程当中,感受遇到的最多的就是空指针这个异常,以下图,我在这里分享一些我通常而言解决这一系列问题的一些技巧。
问题1解决方案:
(1)首先,在下面的地方能够看见出错的地方在哪里,由于为何会出现空指针呢,就是由于咱们想要索引的地方就是一个null,因此确定就会出现异常,所以呢,就通常而言我就再找一个新指针,做为一个测试指针,找到出错在哪一步。(这里确定会有人说为何不用bug,由于我以为这个找错也是一种方法,可是就我我的而言,我以为bug一点一点的又点慢,因此就找了新方法)
(2)而后我通常而言会在循环里找问题,由于有时候就是由于多移了一步可能就致使了这一个问题,因此咱们能够给他减或加一次循环进行查看,结果是否能够成功输出。
因为上周没有进行测试,因此没有错题总结
代码调试中的问题和解决过程, 一个问题加1分
我以为这个中秋节过的很是充实,但愿本身本身尽快再找到更好的状态去面对新的学期,让本身能够学到更多知识,可让本身在这学期能够有更多的收获。
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | |
---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 |
第一周 | 0/0 | 1/1 | 6/6 |
第二周 | 1313/1313 | 1/2 | 20/26 |
第三周 | 901/2214 | 1/3 | 20/46 |
技能 | 课前评估 | 课后评估 |
---|---|---|
对编程总体的理解 | 2 | 6 |
架构设计、模块化设计、接口设计 | 2 | 6 |
效能分析及改进 | 2 | 6 |
处理大数据 | 1 | 6 |
处理命令行参数和文件系统 | 1 | 6 |
自主学习的能力 | 5 | 7 |