zoukankan      html  css  js  c++  java
  • 队列

    队列

      队列是一种常见的线性结构,遵循先进先出的原则,即先存入队列的元素要先取出,后存入队列的元素要后取出。

      队列的插入操作称为入队,入队在队尾进行;队列的删除操作称为出队,出队在队头进行。因此需要front和rear两个变量分别记录队头和队尾的位置,front随着出队操作而改变,rear随着入队操作而改变。

      具体操作如下:

      1. 定义队列时需要定义三个变量:存储容量maxSize、队头位标front、队尾位标rear。其中front存储队头元素的位标,rear存储队尾元素下一位置的位标。

      2. 入队:先判断队列是否已满,没有满就可以进行入队操作。元素入队后,rear需要自增,即rear++。

      3. 出队:先判断队列是否为空,不为空就可以进行出队操作。元素出队后,front需要自增,即front++。

      4. 判空:front == rear。

      5. 判满:rear == maxSize。

      以一个存储容量为5的队列为例,初始化后front = rear = 0:

      

      插入一个元素,rear自增:

      

      弹出一个元素,front自增:

      

      而当在4号位置插入元素后,rear = 5,此时表示队列已满:

      

      可以发现,front前面的空间已经无法再使用。

      也就是说,队列每个存储空间只能使用一次,无法复用。这是队列的一个重大缺陷。

    代码实现

      入队:

    1 public void enQueue(E e) {
    2     if (isFull()) throw new QueueException("队列已满!");
    3     elem[rear++] = e;
    4 }
    enQueue

      出队:

    1 public E deQueue() {
    2     if (isEmpty()) throw new QueueException("队列为空!");
    3     E e = elem[front];
    4     elem[front++] = null;
    5     return e;
    6 }
    deQueue

      获取队头元素:

    1 public E getHead() {
    2     if (isEmpty()) return null;
    3     return elem[front];
    4 }
    getHead

      判空:

    1 public boolean isEmpty() {
    2     return front == rear;
    3 }
    isEmpty

      判满:

    1 public boolean isFull() {
    2     return rear == maxSize;
    3 }
    isFull

    循环队列

      循环队列是对队列的一种改进,具体为:rear不再是普通的自增,而是循环自增,即rear = (rear + 1) % maxSize。这样就可以实现队列的复用。

      以存储容量为5的循环队列为例:

      

      可以看到,插入元素5后,rear循环自增,回到了0号单元的位置。

      但是,在这种情况下:

      

      如果再插入一个元素,就会变成:

      

      可以看到,这时队列已满,front == rear。

      新的问题出现了:front == rear时,无法确定队列为空还是队列已满。此时有两种解决思路:

      1. 增加变量length表示队列中元素的个数。length == 0就表示队列为空,length == maxSize就表示队列已满。

      2. 预留一个空间。front == rear表示队列为空,front == (rear + 1) % maxSize表示队列已满。

    代码实现

      采用第二种解决思路,预留一个空间。

      入队:

    1 public void enQueue(E e) {
    2     if (isFull()) throw new QueueException("队列已满!");
    3     elem[rear] = e;
    4     rear = (rear + 1) % maxSize;
    5 }
    enQueue

      出队:

    1 public E deQueue() {
    2     if (isEmpty()) throw new QueueException("队列为空!");
    3     E e = elem[front];
    4     elem[front] = null;
    5     front = (front + 1) % maxSize;
    6     return e;
    7 }
    deQueue

      获取队头元素:

    1 public E getHead() {
    2     if (isEmpty()) return null;
    3     return elem[front];
    4 }
    getHead

      判空:

    1 public boolean isEmpty() {
    2     return front == rear;
    3 }
    isEmpty

      判满:

    1 public boolean isFull() {
    2     return front == (rear + 1) % maxSize;
    3 }
    isFull
  • 相关阅读:
    POJ 2007 Scrambled Polygon (极角排序)
    POJ 1113 Wall (凸包 + 思维)
    POJ 2074 Line of Sight(求直线交点 + 思维)
    POJ 1584 A Round Peg in a Ground Hole(凸多边形判断 + 点是否在多边形内 + 点到线段的最短距离)
    HDU 4623 Crime (状压DP + 数学优化)
    P4755 Beautiful Pair
    CF235C Cyclical Quest
    luoguP4449 于神之怒加强版
    扩展KMP
    P4397 [JLOI2014]聪明的燕姿
  • 原文地址:https://www.cnblogs.com/lqkStudy/p/11509422.html
Copyright © 2011-2022 走看看