數據結構:隊列的概念和實現

包括:

一. 隊列的概念

二. 順序存儲結構 和 鏈式存儲結構的 隊列的實現


一. 隊列的概念

        隊列即在表的一端進行插入,在表的另一端進行刪除。刪除的一端稱爲隊頭或者隊首,插入的一端稱爲隊尾。插入元素稱爲進隊或者入隊,刪除元素稱爲出隊。特點:先進先出表。隊列的存儲結構分爲順序存儲結構和鏈式存儲結構。 


二. 順序存儲結構 和 鏈式存儲結構的 隊列的實現

順序存儲結構的隊列實現:

        需要一個數組 和 兩個指針(例如 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區別


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章