【資料結構】佇列(順序佇列、鏈佇列)的JAVA程式碼實現
佇列(queue)是一種特殊的線性表,只允許在表的一端進行插入操作而在另一端進行刪除的線性表。進行插入操作的端稱為隊尾,進行刪除操作的一端稱為隊頭。佇列中沒有資料元素時稱為空佇列。
佇列的操作是按照先進先出(first in first out)或後進後出(last in last out)的原則進行的。因此,佇列又被稱為FIFO表。它的實現方式主要有順序佇列、鏈佇列兩種。
佇列的抽象資料模型
- 資料元素:可以為任意型別,只要同屬於一種資料型別即可;
- 資料關係:資料元素之間呈線性關係;
- 資料操作:對佇列的基本操作定義在IQueue中,程式碼如下:
public interface IQueue<E> {
boolean enqueue(E item); //入佇列操作
E dequeue(); //出佇列操作
E peek(); //取對頭元素
int size(); //求佇列的長度
boolean isEmpty(); //判斷佇列是否為空
boolean isFull(); //判斷佇列是否為滿
}
佇列的實現方式
順序佇列
用一片連續的儲存空間來儲存佇列中的資料元素,這樣的佇列稱為順序佇列。類似於順序棧,用一維陣列來存放順序佇列中的資料元素。隊頭設定在最近一個已經離開佇列的元素所佔的位置,用front表示;隊尾設定在最近一個進行入佇列的元素位置,用rear表示。front和rear隨著插入和刪除而變化。當佇列為空時,front=rear=-1。
當有資料元素入佇列時,隊尾指示器rear加1,當有資料元素出佇列時,隊頭指示器front加1。當front=rear時,表示佇列為空,當隊尾指示器rear達到陣列的上限處而front為-1時,佇列為滿。隊尾指示器rear的值大於對頭指示器front的值,佇列中的元素個數可以由rear-front求得。
但是!有時候,佇列未滿但再有一個元素入隊就會出現溢位。但事實上佇列並未滿,還有空閒空間,這種情況成為“假溢位”。這是由於佇列“隊尾入隊,隊頭出”的操作原則造成的。解決假溢位的方法是將順序佇列看成是首尾相接的迴圈結構,首尾指示器的關係不變,這種佇列叫迴圈順序佇列。
當隊尾指示器rear達到陣列的上限是,如果還有資料元素入隊並且陣列的第0個空間空閒時,隊尾指示器rear指向陣列的0端。所以,隊尾指示器的加1操作修改為:rear=(rear+1)%maxsize
隊頭指示器的操作也是如此。當隊頭指示器front達到陣列的上限時,如果還有資料元素出隊,隊頭指示器指向陣列的0端。所以,隊頭指示器的加1操作修改為:front=(front+1)%maxsize
這樣又有一個問題,隊滿和隊空的時候,都有rear=front。為了解決這個問題的方法是一般少用一個空間,所以判斷隊空的條件是rear=front,判斷隊滿的條件是(rear+1)%maxsize=front,與此同時,迴圈佇列中資料元素的個數是(rear-front+maxsize)%maxsize。此時,front表示隊頭,rear表示隊尾,兩者的範圍都是0-maxsize-1。
public class SeqQueue<E> implements IQueue<E> {
private int maxsize; //佇列的容量
private E[] data; // 儲存迴圈順序佇列中的資料元素
private int front; // 指示最近一個己經離開佇列的元素所佔的位置
private int rear; // 指示最近一個進行入佇列的元素的位置
//初始化佇列
@SuppressWarnings("unchecked")
public SeqQueue(Class<E> type, int maxsize) {
data = (E[]) Array.newInstance(type, maxsize);
this.maxsize = maxsize;
front = rear = -1;
}
//入佇列操作
public boolean enqueue(E item) {
if (!isFull()) {
rear = (rear + 1) % maxsize;
data[rear] = item;
return true;
} else
return false;
}
//出佇列操作
public E dequeue() {
if (!isEmpty()) {
front = (front + 1) % maxsize;
return data[front];
} else
return null;
}
//取對頭元素
public E peek() {
if (!isEmpty()) {
return data[(front + 1) % maxsize];
} else
return null;
}
//求佇列的長度
public int size() {
return (rear - front + maxsize) % maxsize;
}
// 判斷佇列是否為空
public boolean isEmpty() {
if (front == rear) {
return true;
} else {
return false;
}
}
// 判斷迴圈順序佇列是否為滿
public boolean isFull() {
if ((front == -1 && rear == maxsize - 1)
|| (rear + 1) % maxsize == front) {
return true;
} else {
return false;
}
}
}
鏈佇列
用鏈式儲存結構來儲存佇列中的資料元素,這樣的佇列稱為鏈佇列。同鏈棧一樣,鏈佇列一般也採用單連結串列來表示,設隊頭指示器為front,隊尾指示器rear。
class QueueNode<E>
{
private E data; // 資料域
private QueueNode<E> next; // 引用域
//建構函式
public QueueNode(){}
public QueueNode(E data) {
this.data = data;
}
public QueueNode(E data, QueueNode<E> next) {
this.data = data;
this.next = next;
}
//資料域get屬性
public E getData() {
return data;
}
//資料域set屬性
public void setData(E data) {
this.data = data;
}
//引用域get屬性
public QueueNode<E> getNext() {
return next;
}
//引用域get屬性
public void setNext(QueueNode<E> next) {
this.next = next;
}
}
public class LinkQueue<E> implements IQueue<E> {
private QueueNode<E> front; // 佇列頭指示器
private QueueNode<E> rear; // 佇列尾指示器
private int maxsize; // 佇列的容量,假如為0,不限容量
private int size; // 佇列資料元素個數
// 初始化鏈佇列
public LinkQueue() {
front = rear = null;
size = 0;
maxsize = 0;
}
// 初始化限容量的鏈佇列
public LinkQueue(int maxsize) {
super();
this.maxsize = maxsize;
}
// 入佇列操作
public boolean enqueue(E item) {
QueueNode<E> newnode = new QueueNode<E>(item);
if (!isFull()) {
if (isEmpty()) {
front = newnode;
rear = newnode;
} else {
rear.setNext(newnode);
rear = newnode;
}
++size;
return true;
} else
return false;
}
// 出佇列操作
public E dequeue() {
if (isEmpty())
return null;
QueueNode<E> node = front;
front = front.getNext();
if (front == null) {
rear = null;
}
--size;
return node.getData();
}
// 取對頭元素
public E peek() {
if (!isEmpty()) {
return front.getData();
} else
return null;
}
// 求佇列的長度
public int size() {
// TODO Auto-generated method stub
return size;
}
// 判斷佇列是否為空
public boolean isEmpty() {
if ((front == rear) && (size == 0)) {
return true;
} else {
return false;
}
}
// 判斷佇列是否為滿
public boolean isFull() {
if (maxsize != 0 && size == maxsize) {
return true;
} else {
return false;
}
}
}
總結與分析
- 位於java.util.Queue的介面擴充了java.util.Collection介面,定義了佇列存取元素的基本方法。
相關文章
- 佇列 優先順序佇列 python 程式碼實現佇列Python
- Java版-資料結構-佇列(陣列佇列)Java資料結構佇列陣列
- 【資料結構】順序佇列的實現(c++)資料結構佇列C++
- Redis實現任務佇列、優先順序佇列Redis佇列
- Java版-資料結構-佇列(迴圈佇列)Java資料結構佇列
- 佇列的順序儲存結構佇列
- 【php實現資料結構】鏈式佇列PHP資料結構佇列
- 鏈式佇列—用連結串列來實現佇列佇列
- 佇列的順序儲存--迴圈佇列的建立佇列
- js實現資料結構--佇列JS資料結構佇列
- 使用C#實現順序佇列C#佇列
- 資料結構-佇列資料結構佇列
- 【資料結構-----佇列】資料結構佇列
- 資料結構 - 佇列資料結構佇列
- java 資料結構 之 佇列的實現 (二)Java資料結構佇列
- 佇列-順序儲存佇列
- 順序佇列基本操作佇列
- 棧,佇列,優先順序佇列簡單介面使用佇列
- 三、資料結構演算法-棧、佇列、優先佇列、雙端佇列資料結構演算法佇列
- 【資料結構】堆排序和模擬實現優先順序佇列!!資料結構排序佇列
- 資料結構之php實現佇列資料結構PHP佇列
- 資料結構與演算法——佇列(環形佇列)資料結構演算法佇列
- 資料結構之「佇列」資料結構佇列
- 資料結構-佇列-樹資料結構佇列
- 資料結構—棧/佇列資料結構佇列
- 資料結構-佇列、棧資料結構佇列
- 資料結構-js實現棧和佇列資料結構JS佇列
- 佇列的一種實現:迴圈佇列佇列
- 佇列的鏈式儲存結構的實現佇列
- 資料結構實驗5、鏈佇列的基本操作資料結構佇列
- 佇列、阻塞佇列佇列
- 畫江湖之資料結構【第二話:佇列和棧】佇列資料結構佇列
- 畫江湖之資料結構 [第二話:佇列和棧] 佇列資料結構佇列
- Java優先順序佇列DelayedWorkQueue原理分析Java佇列
- JavaScript資料結構之-佇列JavaScript資料結構佇列
- 資料結構之佇列(Queue)資料結構佇列
- JavaScript資料結構03 – 佇列JavaScript資料結構佇列
- JavaScript資料結構之佇列JavaScript資料結構佇列