基于数组实现Java 自定义Queue队列及应用

Java 自定义队列Queue:

队列的抽象数据类型就是一个容器,其中的对象排成一个序列,我们只能访问和取出排在最前端( Front)的对象,只能在队列的尾部( Rear)插入新对象。正是按照这一规则,才能保证最先被插入的对象首先被删除( FIFO)。java本身是有自带Queue类包,为了达到学习目的已经更好深入了解Queue队列,自己动手自建java Queue类是个很好的学习开始:

基于数组的实现

顺序数组 借助一个定长数组 Q 来存放对象,即可简单地实现队列。那么,为了符合 FIFO 准则,应该如何表示和记录队列中各对象的次序呢? 一种自然的办法就是仿照栈的实现,以 Q[0]作为队首,其它对象顺序往后存放。然而如此一来,每次首元素出队之后,都需要将后续的所有元素向前顺移一个单元若队长为 n,这项工作需要O(n)时间,因此效率很低。 循环数组 为了避免数组的整体移动,可以引入如下两个变量 f 和 r: f:始终等于 Q 的首元素在数组中的下标,即指向下次出队元素的位置 r:始终等于 Q 的末元素的下标加一,即指向下次入队元素的位置 一开始, f = r = 0,此时队空。每次有对象入队时,将其存放于 Q[r],然后 r 加一,以指向下一单元。对称地,每次有对象出队之后,也将 f 加一,指向新的队首元素。这样,对 front()、 enqueue()和 dequeue()方法的每一次调用都只需常数时间。 然而,这还不够。细心的读者或许已经注意到,按照上述约定,在队列的生命期内, f 和 r 始终在单调增加。因此,若队列数组的容量为 N,则在经过 N 次入队操作后, r 所指向的单元必然超出数组的范围;在经过 N 次出队操作后, f 所指向的单元也会出现类似的问题。 解决上述问题的一种简便方法,就是在每次 f 或 r 加一后,都要以数组的长度做取模运算,以保证其所指单元的合法性。就其效果而言,这就相当于把数组的头和尾相联,构成一个环状结构。 基于上述构想,可以得到如 下所示java代码:

Queue类:

package com.queue;import java.util.Arrays;/** * * @author gannyee * */{CAPACITY = 1024;capacity;front;tail;Object[] array;() {this.capacity = CAPACITY;array = new Object[capacity];front = tail = 0;}() {if (isEmpty())return 0;elsereturn (capacity + tail – front) % capacity;}() {return (front == tail);}(Object element) throws ExceptionQueueFull {if (getSize() == capacity – 1)throw new ExceptionQueueFull(“Queue is full”);array[tail] = element;tail = (tail + 1) % capacity;}Object dequeue() throws ExceptionQueueEmpty {Object element;if (isEmpty())throw new ExceptionQueueEmpty(“Queue is empty”);element = array[front];front = (front + 1) % capacity;return element;}Object frontElement() throws ExceptionQueueEmpty {if (isEmpty())throw new ExceptionQueueEmpty(“Queue is empty”);return array[front];}() {Object[] arrayList = new Object[getSize()];for (int i = front,j = 0; j < getSize(); i ++,j ++) {arrayList[j] = array[i];}System.out.println(“All elements of queue: “+ Arrays.toString(arrayList));}}

自定义ExceptionStackEmpty异常类:

package com.queue;{() {}(String mag) {System.out.println(mag);}}

自定义ExceptionStackFull异常类

package com.queue;{() {}(String mag) {System.out.println(mag);}}

测试类:

package /** * QueueTest * @author gannyee * */public class QueueTest {public static void main(String[] args) {// TODO Auto-generated method stubQueue queue = new Queue();System.out.println(“The size of queue is: ” + queue.getSize());System.out.println(“Is empty: ” + queue.isEmpty());try {queue.enqueue(8);queue.enqueue(3);queue.enqueue(5);queue.enqueue(7);queue.enqueue(9);queue.getAllElements();System.out.println(“The size of queue is: ” + queue.getSize());System.out.println(“Is empty: ” + queue.isEmpty());System.out.println(“The front element of queue: “+ queue.frontElement());System.out.println(queue.dequeue());System.out.println(queue.dequeue());System.out.println(queue.dequeue());System.out.println(queue.dequeue());System.out.println(queue.dequeue());System.out.println(“The size of queue is: ” + queue.getSize());System.out.println(“Is empty: ” + queue.isEmpty());} catch (ExceptionQueueFull e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ExceptionQueueEmpty e) {// TODO Auto-generated catch blocke.printStackTrace();}}}接受失败等于回归真实的自我,接受失败等于打破完美的面具,

基于数组实现Java 自定义Queue队列及应用

相关文章:

你感兴趣的文章:

标签云: