队列
队列是先进先出的数据结构。
队列的基于数组实现的代码如下:
/**
* 队列的java实现代码
*/
public class QueueApp {
public static class Queue {
private int maxSize;
private long[] queArray;
private int front;
private int rear;
private int nItems;
public Queue(int s) {
maxSize = s;
queArray = new long[maxSize];
front = 0;
rear = -1;
}
// --------------以下是增删改查-------------------
public void insert(long j) {
if (rear == maxSize - 1) {
rear = -1;
// 如果插入操作是rear加一后,在对为指针所指的位置处插入新的数据。
//但是当rear指针指向数组的顶端即maxSize位置的时候,再插入数据项之前,他 必须回绕道数组的底端。
//回绕操作把rear设置为-1,因此当rear加1后,他等于0,师叔祖低端的下标值。
}
queArray[++rear] = j;
nItems++;
}
public long remove() {
long temp = queArray[front++];// 移除数据增加头指针的下标
if (front == maxSize) {
front = 0;
}
nItems--;
return temp;
}
public long peekFront() {
return queArray[front];
}
public boolean isEmpty() {
return (nItems == 0);
}
public boolean isFull() {
return (nItems == maxSize);
}
public int size() {
return nItems;
}
}
/**
* 测试一下我们的队列
*
* @param args
*/
public static void main(String[] args)
{
Queue theQueue = new Queue(5); // queue holds 5 items
theQueue.insert(10); // insert 4 items
theQueue.insert(20);
theQueue.insert(30);
theQueue.insert(40);
theQueue.remove(); // remove 3 items
theQueue.remove(); // (10, 20, 30)
theQueue.remove();
theQueue.insert(50); // insert 4 more items
theQueue.insert(60); // (wraps around)
theQueue.insert(70);
theQueue.insert(80);
while( !theQueue.isEmpty() ) // remove and display
{ // all items
long n = theQueue.remove(); // (40, 50, 60, 70, 80)
System.out.print(n);
System.out.print(" ");
}
System.out.println("");
} // end main()
}
队列的的效率
- 和栈一样,队列中插入数据项和移除数据项的时间复杂度均为O(1)
双端队列
- 双端队列就是一个两端都是结尾的队列。队列的每一段都可以插入数据项和移除数据项。
双端队列与栈和队列相比,是一种多用途的数据结构,在容器类库中有事会用双端队列来提供栈和队列的两种功能。但是,双端队列不像栈和队列那么常用,因此这里就不在深入研究它。
优先级队列
- 优先级队列是是比栈和队列更专用的数据结构。向普通队列一样,优先级队列有一个队头和队尾,并且也是从对头移除数据。不过在优先级队列中,数据项按关键字有序,这样关键字最小的数据项(或者在某些实现中关键字最大的数据项)总是在对头。数据项插入的时候会按照顺序插入到合适的位置以确保队列的顺序。
- 代码实现如下(基于数组实现)PS:在数据项个数比较少或者不关心速度的情况下,用数组实现优先级队列还可以满足要求。如果数据项很多,或速度很重要时,采用堆是更好的选择。
class PriorityQ
{
// array in sorted order, from max at 0 to min at size-1
private int maxSize;
private long[] queArray;
private int nItems;
//-------------------------------------------------------------
public PriorityQ(int s) // constructor
{
maxSize = s;
queArray = new long[maxSize];
nItems = 0;
}
//-------------------------------------------------------------
public void insert(long item) // insert item
{
int j;
if(nItems==0) // if no items,
queArray[nItems++] = item; // insert at 0
else // if items,
{
for(j=nItems-1; j>=0; j--) // start at end,
{
if( item > queArray[j] ) // if new item larger,
queArray[j+1] = queArray[j]; // shift upward
else // if smaller,
break; // done shifting
} // end for
queArray[j+1] = item; // insert it
nItems++;
} // end else (nItems > 0)
} // end insert()
//-------------------------------------------------------------
public long remove() // remove minimum item
{ return queArray[--nItems]; }
//-------------------------------------------------------------
public long peekMin() // peek at minimum item
{ return queArray[nItems-1]; }
//-------------------------------------------------------------
public boolean isEmpty() // true if queue is empty
{ return (nItems==0); }
//-------------------------------------------------------------
public boolean isFull() // true if queue is full
{ return (nItems == maxSize); }
//-------------------------------------------------------------
} // end class PriorityQ
////////////////////////////////////////////////////////////////
class PriorityQApp
{
public static void main(String[] args)
{
PriorityQ thePQ = new PriorityQ(5);
thePQ.insert(30);
thePQ.insert(50);
thePQ.insert(10);
thePQ.insert(40);
thePQ.insert(20);
while( !thePQ.isEmpty() )
{
long item = thePQ.remove();
System.out.print(item + " "); // 10, 20, 30, 40, 50
} // end while
System.out.println("");
} // end main()
//-------------------------------------------------------------
} // end class PriorityQApp
insert方法先检查队列中是否有数据项,如果没有,就插入到下标为0的单元里。否则,从数组顶部开始上移存在的数据项,直到找到新数据项应当插入的位置,然后插入新数据,并把nItems加1。
优先队列的效率
插入操作需要O(N)的时间,而删除操作则需要O(1)的时间。