隊列是一種特殊的線性表,特殊之處在於它只允許在表的前端(front)進行刪除操作,而在表的后端(rear)進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。隊列中沒有元素時,稱為空隊列。
隊列的數據元素又稱為隊列元素。在隊列中插入一個隊列元素稱為入隊,從隊列中刪除一個隊列元素成為出隊。因為隊列只允許在一段插入,在另一端刪除,所以只有最早進入隊列的元素才能最先從隊列中刪除,故隊列又稱為先進先出(FIFO—first in first out)線性表。
順序隊列中的溢出現象:
(1) "下溢"現象:當隊列為空時,做出隊運算產生的溢出現象。“下溢”是正常現象,常用作程序控制轉移的條件。
(2)"真上溢"現象:當隊列滿時,做進棧運算產生空間溢出的現象。“真上溢”是一種出錯狀態,應設法避免。
(3)"假上溢"現象:由於入隊和出隊操作中,頭尾指針只增加不減小,致使被刪元素的空間永遠無法重新利用。當隊列中實際的元素個數遠遠小於向量空間的規模時,也可能由於尾指針已超越向量空間的上界而不能做入隊操作。該現象稱為"假上溢"現象。
圖from baike
隊列的常用操作:
(1)初始化隊列: 初始條件:隊列 不存在。操作結果:構造了一個空隊或者帶有一個對頭的的隊列;
(2)入隊操作:初始條件: 隊列存在。操作結果: 對已存在的隊列,插入一個元素x 到隊尾,隊發生變化;
(3)出隊操作:初始條件: 隊列 存在且非空,操作結果: 刪除隊首元素,並返回其值,隊發生變化;
(4)讀隊頭元素:初始條件: 隊列 存在且非空,操作結果: 讀隊頭元素,並返回其值,隊不變;
(5)判隊空操作:初始條件: 隊列 存在,操作結果: 若隊列為空則返回為true,否則返回為false;
(6)清空隊列操作:初始條件:隊列存在,操作結果:清空隊列,隊列的長度為0;
(7)計算隊列長度:初始條件:隊列存在,操作結果:計算並返回隊列長度。
隊列常用操作算法的時間和空間復雜度均為O(1);
實現代碼:
package com.wxisme.linkqueue;
import java.util.Scanner;
/**
* 鏈隊列的實現
* @time 2015/8/16 0:16
* @author wxisme
*
*/
public class LinkQueue<T> {
private class Node {
private T data;
private Node next;
public Node() {}
public Node(T data) {
this.data = data;
}
}
private Node front; /*隊頭*/
private Node rear; /*隊尾*/
private int size; /*長度*/
public LinkQueue() {
front = null;
rear = null;
}
public LinkQueue(T data) {
front = new Node(data);
rear = front;
size ++;
}
//隊列的長度
public int size() {
return size;
}
//從隊尾入隊
public void add(T data) {
if(front == null) {
front = new Node(data);
rear = front;
size ++;
}
else {
Node node = new Node(data);
rear.next = node;
rear = node;
size ++;
}
}
//從隊頭出隊
public T remove() {
T t = null;
if(front != null) {
t = front.data;
Node node = front;
front = front.next;
node.next = null;//釋放對頭元素的引用,等待垃圾回收。
size --;
}
else {
try {
throw new Exception("隊列已經為空,不能移除元素!");
} catch (Exception e) {
e.printStackTrace();
}
}
return t;
}
//讀取對頭元素
public T peek() {
if(front == null) {
try {
throw new Exception("隊列為空,不能讀取對頭元素!");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
else {
return front.data;
}
}
//清空隊列
public void clear() {
front = rear = null;
size = 0;
}
//判斷是否為空
public boolean isEmpty() {
return size==0;
}
public String toString() {
if(isEmpty()) {
return "[]";
}
else {
StringBuilder str = new StringBuilder("[" + front.data);
for(Node node=front.next; node!=null; node=node.next) {
str.append(","+node.data);
}
str.append("]");
return str.toString();
}
}
/**
* 測試代碼
* @param args
*/
public static void main(String[] args) {
LinkQueue<Character> queue = new LinkQueue<Character>();
Scanner scan = new Scanner(System.in);
for(int i=0; i<5; i++) {
queue.add((char)('a'+i));
}
System.out.println(queue);
queue.remove();
System.out.println(queue);
System.out.println("隊列是否為空:" + queue.isEmpty());
System.out.println("隊列的長度:" + queue.size());
System.out.println("隊頭元素為:" + queue.peek());
System.out.println("清空隊列");
queue.clear();
System.out.println("隊列是否為空:" + queue.isEmpty());
}
}
測試結果:
[a,b,c,d,e]
[b,c,d,e]
隊列是否為空:false
隊列的長度:4
隊頭元素為:b
清空隊列
隊列是否為空:true
