zoukankan      html  css  js  c++  java
  • 5、队列的顺序存储结构:循环队列、两种方法

    队列的ADT:

     1 package ren.laughing.datastructure.base;
     2 
     3 import ren.laughing.datastructure.exception.QueueEmptyException;
     4 
     5 /**
     6  * 队列Queue的ADT:先进先出
     7  * 在队列中把插入数据元素的一端称为 队尾(rear), 删除数据元素
     8  * 的一端称为 队首(front)。向队尾插入元素称为 进队或入队,
     9  * 新元素入队后成为新的队尾元素;从队列中删除元素称为 离队或出队,
    10  * 元素出队后,其后续元素成为新的队首元素。
    11  * @author Laughing_Lz
    12  * @time 2016年4月7日
    13  */
    14 public interface Queue {
    15     //返回队列的大小
    16     public int getSize();
    17     //判断队列是否为空
    18     public boolean isEmpty();
    19     //数据元素 e 入队
    20     public void enqueue(Object e);
    21     //队首元素出队
    22     public Object dequeue() throws QueueEmptyException;
    23     //取队首元素
    24     public Object peek() throws QueueEmptyException;
    25     }

    循环队列的顺序存储实现,采用少一存储空间的方法:

     1 package ren.laughing.datastructure.baseImpl;
     2 
     3 import ren.laughing.datastructure.base.Queue;
     4 import ren.laughing.datastructure.exception.QueueEmptyException;
     5 /**
     6  * 队列Queue的顺序存储,此处使用循环队列,逆时针,方法一
     7  * ★循环队列:难点在于如何判断队空和队满
     8  * 方法一:★少使用一个存储空间,即:当队尾指针的下一指针指向队首指针时,就停止入队。
     9  * 判决:队空:rear=front,队满:(rear+1)%capacity = float
    10  * 方法二:★增设一个标志size,以size?=MAX区别队满队空
    11  * 判决:队空:size = 0,队满:size = capacity
    12  * @author Laughing_Lz
    13  * @time 2016年4月7日
    14  */
    15 public class QueueArray implements Queue{
    16     private static final int CAP=7;//队列默认容量大小
    17     private Object[] elements;
    18     private int capacity;//数组的实际大小 elements.length
    19     private int front;
    20     private int rear;
    21     
    22     public QueueArray() {
    23         this(CAP);
    24     }
    25     public QueueArray(int cap) {
    26         this.elements = new Object[capacity];
    27         this.capacity = cap+1;//这里数组实际大小capacity比队列容量cap大1
    28         this.front = 0;
    29         this.rear = 0;
    30     }
    31     //获取队列的容量
    32     @Override
    33     public int getSize() {
    34         return (rear-front+capacity)%capacity;//返回队列的实际容量,小于等于capacity-1
    35     }
    36     //判断是否队空
    37     @Override
    38     public boolean isEmpty() {
    39         if(rear == front){
    40             return true;
    41         }else{
    42             return false;
    43         }
    44     }
    45     //入队:相当于在insertAfter队尾
    46     @Override
    47     public void enqueue(Object e) {
    48 //        if(getSize()==capacity-1){//同下,判断队列容量是否已满
    49         if((rear+1)%capacity == front){//判断是否队满
    50             expandSpace();//扩充队列的容量
    51         }
    52         elements[rear] = e;
    53         rear = (rear+1)%capacity;//rear有可能从capacity-1移动到0
    54     }
    55     //出队:相当于在remove队首
    56     @Override
    57     public Object dequeue() throws QueueEmptyException {
    58         if(rear == front){//判断是否队空
    59             throw new QueueEmptyException("错误:队列已空");
    60         }
    61         Object obj = elements[front];
    62         elements[front] = null;//置空
    63         front = (front+1)%capacity;//front有可能从capacity-1移动到0
    64         return obj;
    65     }
    66     //获取队首数据元素
    67     @Override
    68     public Object peek() throws QueueEmptyException {
    69         if(rear == front){//判断是否队空
    70             throw new QueueEmptyException("错误:队列已空");
    71         }
    72         return elements[front];
    73     }
    74     /**
    75      * ★扩充数组长度
    76      */
    77     private void expandSpace() {
    78         Object[] a = new Object[elements.length * 2];
    79         int i = front;
    80         int j = 0;
    81         while(i!=rear){//将从 front 开始到 rear 前一个存储单元的元素复制到新数组
    82             a[j++] = elements[i];
    83             i = (i+1)%capacity;
    84         }
    85         elements = a;
    86         capacity = elements.length;
    87         front  = 0;
    88         rear = j;//重新设置新的队首队尾指针
    89     }
    90 }

    循环队列的顺序存储实现,采用加标志size的方法:

     1 package ren.laughing.datastructure.baseImpl;
     2 
     3 import ren.laughing.datastructure.base.Queue;
     4 import ren.laughing.datastructure.exception.QueueEmptyException;
     5 /**
     6  * 队列Queue的顺序存储,此处使用循环队列,逆时针,方法二
     7  * ★循环队列:难点在于如何判断队空和队满
     8  * 方法一:★少使用一个存储空间,即:当队尾指针的下一指针指向队首指针时,就停止入队。
     9  * 判决:队空:rear=front,队满:(rear+1)%capacity = float
    10  * 方法二:★增设一个标志size,以size?=MAX区别队满队空
    11  * 判决:队空:size = 0,队满:size = capacity
    12  * @author Laughing_Lz
    13  * @time 2016年4月7日
    14  */
    15 public class QueueArray2 implements Queue{
    16     private static final int CAP=8;//队列默认容量大小
    17     private Object[] elements;
    18     private int capacity;//数组的实际大小 elements.length
    19     private int size;//队列容量(空/满判断标志)
    20     private int front;
    21     private int rear;
    22     
    23     public QueueArray2() {
    24         this(CAP);
    25     }
    26     
    27     public QueueArray2(int cap) {
    28         this.elements = new Object[capacity];
    29         this.capacity = cap;//此处cap = capacity
    30         this.size = 0;//队列初始为空
    31         this.front = 0;
    32         this.rear = 0;
    33     }
    34     //获取队列的容量
    35     @Override
    36     public int getSize() {
    37         if(size == capacity){
    38             return capacity;
    39         }else{
    40             return (rear-front+capacity)%capacity;
    41         }
    42     }
    43     //判断是否队空
    44     @Override
    45     public boolean isEmpty() {
    46         if(rear == front&&size !=capacity){
    47             return true;
    48         }else{
    49             return false;
    50         }
    51     }
    52     //入队:相当于在insertAfter队尾
    53     @Override
    54     public void enqueue(Object e) {
    55         if(size  == capacity){//判断是否队满
    56             expandSpace();//扩充队列的容量
    57         }
    58         elements[rear] = e;
    59         rear = (rear+1)%capacity;//rear有可能从capacity-1移动到0
    60         size++;
    61     }
    62     //出队:相当于在remove队首
    63     @Override
    64     public Object dequeue() throws QueueEmptyException {
    65         if(rear == front&&size != capacity){//判断是否队空 (此时size为0)
    66             throw new QueueEmptyException("错误:队列已空");
    67         }
    68         Object obj = elements[front];
    69         elements[front] = null;//置空
    70         front = (front+1)%capacity;//front有可能从capacity-1移动到0
    71         size--;
    72         return obj;
    73     }
    74     //获取队首数据元素
    75     @Override
    76     public Object peek() throws QueueEmptyException {
    77         if(rear == front&&size != capacity){//判断是否队空 (此时size为0)
    78             throw new QueueEmptyException("错误:队列已空");
    79         }
    80         return elements[front];
    81     }
    82     /**
    83      * ★扩充数组长度
    84      */
    85     private void expandSpace() {
    86         Object[] a = new Object[elements.length * 2];
    87         int i = front;
    88         int j = 0;
    89         do{//将从 front 开始到 rear 前一个存储单元的元素复制到新数组
    90             a[j++] = elements[i];
    91             i = (i+1)%capacity;
    92         }while(i!=rear);//
    93         elements = a;
    94         capacity = elements.length;
    95         front  = 0;
    96         rear = j;//重新设置新的队首队尾指针
    97     }
    98 }
    —————————————————————————————————————行走在人猿的并行线——Laughing_Lz
  • 相关阅读:
    我的WCF之旅(1):创建一个简单的WCF程序
    网页设计中颜色的搭配
    CSS HACK:全面兼容IE6/IE7/IE8/FF的CSS HACK
    UVa 1326 Jurassic Remains
    UVa 10340 All in All
    UVa 673 Parentheses Balance
    UVa 442 Matrix Chain Multiplication
    UVa 10970 Big Chocolate
    UVa 679 Dropping Balls
    UVa 133 The Dole Queue
  • 原文地址:https://www.cnblogs.com/Laughing-Lz/p/5364396.html
Copyright © 2011-2022 走看看