包括:
一. 隊列的概念
二. 順序存儲結構 和 鏈式存儲結構的 隊列的實現
一. 隊列的概念
隊列即在表的一端進行插入,在表的另一端進行刪除。刪除的一端稱爲隊頭或者隊首,插入的一端稱爲隊尾。插入元素稱爲進隊或者入隊,刪除元素稱爲出隊。特點:先進先出表。隊列的存儲結構分爲順序存儲結構和鏈式存儲結構。
二. 順序存儲結構 和 鏈式存儲結構的 隊列的實現
順序存儲結構的隊列實現:
需要一個數組 和 兩個指針(例如 front 和 rear),利用數組存儲所有元素,利用兩個指針分別指向隊首 和 隊尾,爲了充分使用空間,一般用環形隊列,即把隊首和隊尾連接起來。當從隊尾插入元素的時候, 進行 rear = ( rear + 1 ) % MaxSize; 同樣,在隊首刪除元素的時候,也是 front = ( front + 1) % MaxSize; 此時會發現,隊空 和 隊滿都是 rear == front ,爲了區別隊空 和 隊滿,通常 少用一個元素,即 (rear + 1)% MaxSize == front 就認爲是 堆滿,對空的判斷條件還是不變, front == rear。
以下爲 順序存儲結構的隊列的簡易實現:
public class SelfQueueImpl {
private static int dataLength = 2;
public static void main(String[] args) {
SqQueue sqQueue = new SqQueue();
sqQueue.enQueue(1);
sqQueue.enQueue(2);
sqQueue.enQueue(3);
System.out.println(sqQueue.deQueue());
System.out.println(sqQueue.deQueue());
System.out.println(sqQueue.deQueue());
}
static class SqQueue{
private Object data[] = new Object[dataLength];
private int front;
private int rear;
//進隊
public void enQueue(Object element){
if(queueIsFull()){
System.out.println("Queue is full, enQueue failed!.");
} else {
data[rear] = element;
rear ++;
resetRear(rear);
System.out.println("enQueue success. data[" + (rear-1) + "] = " + data[rear-1] );
}
}
private void resetRear(int rear) {
if(rear == dataLength){
this.rear = 0;
}
}
private boolean queueIsFull() {
return (rear + 1) % dataLength == front;
}
//出隊
public Object deQueue(){
if(queueIsEmpty()){
System.out.println("Queue is empty, deQueue failed!.");
return null;
} else {
Object object = data[front];
front ++;
resetFront(front);
return object;
}
}
private void resetFront(int front) {
if(front == dataLength){
this.front = 0;
}
}
private boolean queueIsEmpty() {
return rear == front;
}
}
}
輸出爲:
enQueue success. data[0] = 1
Queue is full, enQueue failed!.
Queue is full, enQueue failed!.
1
Queue is empty, deQueue failed!.
null
Queue is empty, deQueue failed!.
null
鏈表存儲結構的隊列實現:
對於鏈表存儲結構,就沒有循環鏈表的概念,也沒有隊滿的概念。對於隊空,由於隊列會維護着 front 和 rear,所以只需要判斷其中一個是否爲空即可。
以下爲 鏈式存儲結構的隊列的簡易實現:
public class SelfQueueImpl_List {
public static void main(String[] args) {
SqQueue sqQueue = new SqQueue();
sqQueue.enQueue(1);
sqQueue.enQueue(2);
sqQueue.enQueue(3);
System.out.println(sqQueue.deQueue());
System.out.println(sqQueue.deQueue());
System.out.println(sqQueue.deQueue());
System.out.println(sqQueue.deQueue());
}
static class SqQueue{
private QNode front;
private QNode rear;
//進隊
public void enQueue(Object object){
if(QueueIsEmpty()){
insert1(object);
} else{
insert2(object);
}
System.out.print("enQueue success. Queue is ");
printQueue();
}
private void printQueue() {
QNode flag = this.front;
while(flag != null ){
System.out.print(" " + flag.getObject());
flag = flag.getNext();
}
System.out.print("\n");
}
private void insert1(Object object) {
QNode qNode = new QNode(object);
this.front = qNode;
this.rear = qNode;
}
private void insert2(Object object) {
rear.setNext(new QNode(object));
rear = rear.getNext();
}
private boolean QueueIsEmpty() {
return this.front == null;
}
//出隊
public Object deQueue(){
if(QueueIsEmpty()){
System.out.println("Queue is empty, deQueue failed!.");
return null;
} else {
Object object = front.getObject();
front = front.next;
return object;
}
}
}
static class QNode{
private Object object;
private QNode next;
public QNode(Object object){
this.object = object;
}
public Object getObject(){
return this.object;
}
public QNode getNext(){
return this.next;
}
public void setNext(QNode qNode){
this.next = qNode;
}
}
}
輸出爲:
enQueue success. Queue is 1
enQueue success. Queue is 1 2
enQueue success. Queue is 1 2 3
1
2
3
Queue is empty, deQueue failed!.
null
下一篇再介紹 Java 的隊列體系結構。
參考:java Queue中 remove/poll, add/offer, element/peek區別