其实在上一堂课讲到了queue的接口设计。本来想将queue整个包含在上一篇文章中,但是对于队列的问题包含了很多东西,便想单独列出来说明一下。
首先我们先了解什么是队列:
队列同样是一种特殊的线性表,其插入和删除的操作分别在表的两端进行,队列的特点就是先进先出(First In First Out)。我们把向队列中插入元素的过程称为入队(Enqueue),删除元素的过程称为出队(Dequeue)并把允许入队的一端称为队尾,允许出的的一端称为队头,没有任何元素的队列则称为空队。
上篇文章中,由我的教授提出的接口是:
public interface Queue{/*** Update this Queue by adding an item on the newest end;
*@paramitem the item to add;*/
voidenqueue(Item item);/*** Update this Queue by taking the oldest item off the queue
*@returnthe item or null if there is no such item;*/Item dequeue();/***@returntrue if the queue is empty;*/
booleanisEmpty();
}
这个接口都没有表明这是一个顺序队列还是一个循环队列。当然对于实际应用,顺序队列会消耗掉大量的内存空间。其中enqueu的时间复杂度是O(1),但是如果在dequeue()的时候进行位移操作,那么整个程序的复杂度为O(n).而对于循环列表,enqueue仍然是O(1)的复杂度,dequeue则降低为O(1)。
其中关于循环队列在建立的时候包含一个问题,如果将整个队列全部装满,那么front==rear的判断条件符合队列空,也符合队列满!
所以在建立队列的时候,有两种方法来解决这个问题:
1)另设一个标识为来判断是否队列满了;
2)少一个元素空间,规定front指针在rear指针的下一个位置上,即:
队空时:front=rear;
队满时:front=(rear+1)%maxsize
下面,我自己对queue接口进行实现。当然,这是一个循环队列的实现。
其中使用第二种方法对队满进行判断:
public class MyQueue implements Queue{private static int DEFAULT_SIZE=10;privateItem elements[];private intfront,rear;private intsize;publicMyQueue(){
elements=(Item[])newObject[DEFAULT_SIZE];
front=rear=0;
size=0;
}public MyQueue(intcapacity)
{
elements=(Item[])newObject[capacity];
front=rear=0;
size=0;
}public intsize(){returnsize;
}public booleanisEmpty(){return front==rear;
}public voidenqueue(Item data){if(this.front==(this.rear+1)%this.elements.length){
ensureCapacity(this.elements.length*2+1);
}
elements[rear]=data;this.rear=(this.rear+1)%this.elements.length;
size++;
}publicItem dequeue(){
Item temp=this.elements[front];this.front=(this.front)%this.elements.length;
size--;returntemp;
}public void ensureCapacity(intcapacity){
Item[] old=this.elements;this.elements=(Item[])newObject[capacity];int j=0;for(int i=this.front;i!=this.rear;i=(i+1)%old.length){
elements[j++]=old[i];
}
front=0;
rear=j;
}
}
其中扩展了ensureCapaciy()方法。主要是对array长度不够,而扩展队列的扩展。
其实可以看到,循环队列不会要求enqueue的时候将元素往前移动,而降低了复杂度。
但是,今天上课教授告诉我,用LinkList去实现队列和堆栈是一种更好的方法
我:??????
那我们下一次将会使用LinkList实现队列和堆栈。