队列

作者: Leo_up_up | 来源:发表于2020-04-19 21:36 被阅读0次

   队列,是一个先进先出的数据结构,与栈一样,队列也是一种数组与链表的一种的受限操作所形成的特殊数据结构。

相比于栈的先进后出,队列的先进先出是怎么样一个抽象模型呢。

队列模型

队列只支持两个操作,分别是入队和出队,入队只能在队尾进行,出队只能在队头进行。

队列作为一种基础的数据结构,它的应用是十分广泛的。其中以它的一些特殊实现为最,比如循环队列,阻塞队列,并发队列,优先队列等。

下面以数组来实现一个简单的队列。

/**

* 以数组实现队列

*/

public class Queue_4_19 {

private static int DEFAULT_SIZE =10;

private int tail =0;// 队尾

    private int font =0;// 队头

    private int[]array;

public Queue_4_19() {

this(DEFAULT_SIZE);

}

public Queue_4_19(int size) {

array =new int[size];

}

private boolean enqueue(int val) {

if (tail ==array.length -1) {// 判满

            return false;

}

array[tail++] = val;

return true;

}

private boolean dequeue() {

if (font ==tail) {// 判空

            return false;

}

font++;

return true;

}

}

从上面的代码可以看出来,当tail==n时,这个队列就无法插入新元素了,那么当里面的元素全部出队时,这个队列就不可用了,那么我们就可以设计一个循环队列来解决这种问题。

与普通队列不同的是,循环队列可以理解为一个圆形环。下面放上两张图,可以更好的理解。

循环队列A 循环队列B

从上图的循环队列A可以看出,此时的队尾已经指向了数组的最后一个下标,按照普通的队列,这个时候已经无法插入了,但是我们可以看到,此时数组下标0-3都是没有元素,表明可以插入的,那我们可以怎么做呢,这个时候,我们把数据a放进数组,但是我们不把tail更新为8,而是更新为0,然后继续放入b,把tail更新为1。然后就变成了循环队列B这个样子。

这就是循环队列的设计理念,与普通队列一样,循环队列的关键也在于判空与判满,就像循环队列A哪个图,如果依然按照tail==array.length -1来判满,那么就无法插入新的数据,这是不对的。但是判空与普通队列一样,依然是font==tail。

下面上一张图,可以更好理解怎么判满:

循环队列判满

计算下标,多画一些图,就可以得到规律,当(tail+1)%(array.length)==font时,就标明队列已经满了,我们这个样子设计,会浪费一个存储单元,为什么要这个样子,因为如果tail==font,那么就和判空冲突了,当然,这个也可以解决,使用一个计数器就可以,不过相比于在维护一个计数器,单纯浪费一个存储单元更可以接受,也更简单。下面写出循环队列的实现代码:

/**

* Insert an element into the circular queue. Return true if the operation is successful.

*/

public boolean enQueue(AnyType value) {//需要判断满

    if (isFull())

return false;

array[tail] = value;

tail = (tail +1) %array.length;

return true;

}

/**

* Delete an element from the circular queue. Return true if the operation is successful.

*/

public boolean deQueue() {

if(isEmpty())

return false;

font = (font+1)%array.length;

return true;

}

/**

* Checks whether the circular queue is empty or not.

*/

public boolean isEmpty() {

return font ==tail;//头指针尾指针指向同一位置

}

/**

* Checks whether the circular queue is full or not.

*/

public boolean isFull() {

return (tail +1) %array.length ==font;

}

这就是循环队列的实现。相比于单纯的队列,更加应用广泛。

阻塞队列

相比于上面的普通队列,循环队列,阻塞队列的应用场景更加广泛,组织队列的含义就是,当队列空的时候,我们就阻止从队头取数据,当队列满的时候,我们就阻止从队尾放数据。

阻塞队列A 阻塞队列B

基于这样一个概念,我们可以轻松的设计出一个生产者--消费者模型,可以有效协调生产者和消费者的效率,当生产者生产过多二消费不了时,队列就会满,此时就停止生产,而当消费过多生产不够时,就阻止消费操作。同时,我们也可以配置多个消费者同时消费,当生产过多时,这样可以更好的利用资源。

上面就是队列的一些概念与实现。也可以做一些专门题目进行训练。

相关文章

  • 队列

    队列特性 对比队列和栈 基于数组的队列 对比队列学习循环队列 循环队列难点 阻塞队列 并发队列 应用:线程池中拒绝...

  • 队列

    文章结构 什么是队列 实现队列顺序队列链式队列循环队列 Java中的队列 1. 什么是队列 队列也是一种操作受限的...

  • iOS底层-- GCD源码分析(1)-- dispatch_qu

    手动目录认识队列队列的结构队列的产生主队列全局队列创建的队列管理队列 代码版本dispatch version :...

  • 队列,异步,同步,线程通俗理解

    一、队列 串行队列 并行队列 主队列(只在主线程执行的串行队列) 全局队列(系统的并行队列) 二、 任务(是否具有...

  • GCD基础总结一

    上代码~ 同步串行队列 同步并行队列 异步串行队列 异步并行队列 主队列同步 会卡住 主队列异步

  • OC多线程

    队列创建 线程与队列 队列线程间通信 队列组

  • GCD

    获得主队列 获得全局队列 串行队列 异步队列 同步队列 阻隔队列 (像栅栏一样 ) 例如 A -->栅栏 --...

  • 数据结构第三篇 队列

    队列的特性 前进先出。 我们来大致描述下进出队列的情况。 进队列 1 进队列现在队列是 12 进队列现在队列是 1...

  • 利用链表实现队列

    队列成员变量: 队列长度 队列头节点 队列尾节点队列方法: 队列包含元素个数 队列是否为空 进队操作 出队操作 d...

  • Git 常用操作命令(持续更新)

    当前更新到stash队列 查看stash队列 清空队列 删除某个队列

网友评论

      本文标题:队列

      本文链接:https://www.haomeiwen.com/subject/agribhtx.html