• 循环队列


    队列概念

      队列(Queue)是限定只能在一端插入、另一端删除的线性表。允许删除的一端叫做队头(front),允许插入的一端叫做队尾(rear),没有元素的队列称为“空队列”。

      队列具有先进先出(FIFO)的特性。

    普通顺序队列存在的问题

      在普通顺序队列中,入队的操作就是先将尾指针rear右移一个单位,然后将元素值赋值给rear单位。出队时,则是头指针front后移一个单位。像这样进行了一定数量的入队和出队操作后,可能会出现这样的情况:

      尾指针rear已指到数组的最后有一个元素,即rear==MaxLen-1,此时若再数组的前面部分可能还有很多闲置空间,即这种溢出并非是真的没有可用的存储空间,故称这种溢出现象为“假溢出”。显然,必须要解决这一块假溢出的问题,否则顺序队列就没有太多使用价值。

    循环队列

           

    说明:

      1. 判断满条件为  front =  (rear + 1) % size  即满

           2. 每入队一个元素, tail =  (tail + 1) % size

           3. 令队列空间中的一个单元闲置,使得队列非空时,rear与front之间至少间隔一个空闲单。  

     

    循环队列: 

      1 public class LoopQueue<E> implements Queue<E> {
      2 
      3     private E[] data;
      4     private int front,tail;
      5     private int size;
      6 
      7     public LoopQueue(int capacity){
      8         //需要多一个空间 留空
      9         data = (E[])new Object[capacity+1];
     10         front = 0;
     11         tail = 0;
     12         size = 0;
     13     }
     14 
     15     public LoopQueue(){
     16         this(10);
     17     }
     18 
     19     public int getCapacity(){
     20         return data.length - 1;
     21     }
     22 
     23     @Override
     24     public boolean isEmpty(){
     25         return front == tail;
     26     }
     27 
     28     @Override
     29     public int getSize(){
     30         return size;
     31     }
     32 
     33     //入队
     34     @Override
     35     public void enqueue(E e){
     36         //队列满了判断
     37         if ((tail + 1) % data.length == front)
     38             resize(getCapacity() * 2);
     39 
     40         data[tail] = e;
     41         tail = (tail + 1) % data.length;
     42         size++;
     43     }
     44 
     45     //出队
     46     @Override
     47     public E dequeue(){
     48 
     49         if (isEmpty())
     50             throw new IllegalArgumentException("Cannot dequeue from an empty queue");
     51 
     52         E ret = data[front];
     53         //data[front] = null;
     54         front = (front + 1) % data.length;
     55         size --;
     56 
     57         //缩容
     58         if (size == getCapacity() / 4 && getCapacity() / 2 != 0 )
     59             resize(getCapacity() / 2);
     60 
     61         return ret;
     62     }
     63 
     64     @Override
     65     public E getFront(){
     66         if (isEmpty())
     67             throw new IllegalArgumentException("Cannot dequeue from an empty queue");
     68 
     69         return data[front];
     70     }
     71 
     72     private void resize(int newCapacity){
     73         E[] newData = (E[])new Object[newCapacity + 1];
     74         for (int i = 0; i < size; i++){
     75             //把旧的数组的首元素 放入到新的元素中 ,这里不用i,因为i不一定是首位元素
     76             newData[i] = data[(front + i) % data.length];
     77         }
     78 
     79         data = newData;
     80         front = 0;
     81         tail = size;
     82     }
     83 
     84     //覆盖父类
     85     @Override
     86     public String toString() {
     87         StringBuilder res = new StringBuilder();
     88         res.append(String.format("Queue:size = %d,capacity = %d
    ", size, getCapacity()));
     89         res.append("front [");
     90         for (int i = front; i != tail; i = (i + 1) % data.length){
     91             res.append(data[i]);
     92             if ((i + 1) % data.length != tail)
     93                 res.append(", ");
     94         }
     95         res.append("] tail");
     96 
     97         return res.toString();
     98     }
     99 
    100 }
  • 相关阅读:
    项目有大小,生存各有道
    学习Spark——那些让你精疲力尽的坑
    学习Spark——环境搭建(Mac版)
    小程序新能力-个人开发者尝鲜微信小程序
    如何写出好代码
    华为手机nova2s使用第三方字体库
    std::string与std::wstring互相转换
    Steam安装Google Earth VR
    osgearth2.8关于RectangleNodeEditor编辑点不可见的问题
    Qt生成ui文件对应的.h和.cpp文件
  • 原文地址:https://www.cnblogs.com/loveyouyou616/p/9467263.html
Copyright © 2020-2023  润新知