隊列是一種先進先出的數據結構
隊列上的插入操作叫入隊列,刪除操作叫出隊列
隊列有對頭,和隊尾
就想超市結賬排隊一樣,顧客總是排到隊列的尾部(隊尾),也就是說在隊列的尾部入隊列,隊列的頭部出隊列。
如何在java中實現隊列有兩種選擇,一種是通過數組實現,一種是通過鏈表實現。
數組實現的隊列:
//隊列接口
interface Queue<T>{
boolean enQueue(T k);
T deQueue();
boolean isEmpty();
void clear();
int length();
}
//順序隊列
class ArrayLinerQueue<T> implements Queue<T>{
private int size=0;
private int head=0;
private int tail=0;
private Object[] data = new Object[4];
@Override
public boolean enQueue(T k) {
// 判斷是否需要進行數組擴容
if (tail >= data.length) {
resize();
}
System.out.println("enQueue: " + k);
data[tail++] = k;
size++;
return true;
}
/**
* 數組擴容
*/
private void resize() {
System.out.println("數組空間不夠,擴容");
Object[] temp = new Object[data.length * 2];
for (int i = head; i < tail; i++) {
temp[i] = data[i];
data[i] = 0;
}
data = temp;
}
@Override
public T deQueue() {
if (size == 0) {
return null;
}
System.out.println("deQueue:"+(T)data[head]);
size--;
return (T)data[head++];
}
@Override
public boolean isEmpty() {
return size==0;
}
@Override
public void clear() {
// 將數組中的數據置爲null, 方便GC進行回收
for (int i = 0; i < size; i++) {
data[size] = null;
}
size = 0;
head=0;
tail=0;
}
@Override
public int length() {
return size;
}
@Override
public String toString() {
return "ArrayQueue{" +
"size=" + size +
", head=" + head +
", tail=" + tail +
", data=" + Arrays.toString(data) +
'}';
}
}
//順序循環隊列
class ArrayCycleQueue<T> implements Queue<T>{
private int size=0;
private int head=0;
private int tail=0;
private Object[] data = new Object[4];
@Override
public boolean enQueue(T k) {
// 判斷是否需要進行數組擴容
if (head==tail && head!=0) {
resize();
}
if (tail>=data.length && head>0){
tail=0;
}
System.out.println("enQueue: " + k);
data[tail++] = k;
size++;
return true;
}
/**
* 數組擴容
*/
private void resize() {
System.out.println("數組空間不夠,擴容");
Object[] temp = new Object[data.length * 2];
for (int i = head+data.length; i < temp.length; i++,head++) {
temp[i] = data[head];
}
for (int i = 0; i < tail; i++) {
temp[i] = data[i];
}
data = temp;
}
@Override
public T deQueue() {
if (size == 0) {
return null;
}
System.out.println("deQueue:"+(T)data[head]);
size--;
return (T)data[head++];
}
@Override
public boolean isEmpty() {
return size==0;
}
@Override
public void clear() {
// 將數組中的數據置爲null, 方便GC進行回收
for (int i = 0; i < size; i++) {
data[size] = null;
}
size = 0;
head=0;
tail=0;
}
@Override
public int length() {
return size;
}
@Override
public String toString() {
return "ArrayQueue{" +
"size=" + size +
", head=" + head +
", tail=" + tail +
", data=" + Arrays.toString(data) +
'}';
}
}
鏈表實現的隊列
//鏈表實現隊列
class LinkedListQueue<T> implements Queue<T>{
private int size=0;
private QueueNode head=null;
private QueueNode tail=null;
@Override
public boolean enQueue(T k) {
System.out.println("enQueue: " + k);
QueueNode queueNode = new QueueNode();
queueNode.setData(k);
if (tail==null){
tail=queueNode;
head=tail;
}else {
tail.setNext(queueNode);
tail=queueNode;
}
size++;
return true;
}
@Override
public T deQueue() {
if (size == 0) {
return null;
}
T tempdata = head.getData();
head=head.getNext();
System.out.println("deQueue:"+tempdata);
size--;
return tempdata;
}
@Override
public boolean isEmpty() {
return size==0;
}
@Override
public void clear() {
size = 0;
head=null;
tail=null;
}
@Override
public int length() {
return size;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
QueueNode temp = head;
while (temp!=null){
sb.append(temp.getData()+" ");
temp=temp.getNext();
}
return "LinkedListQueue{" +
"size=" + size +
", head=" + head.getData() +
", tail=" + tail.getData() +
", queue="+sb.toString()+
'}';
}
private class QueueNode{
private T data;
private QueueNode next;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public QueueNode getNext() {
return next;
}
public void setNext(QueueNode next) {
this.next = next;
}
}
}
測試
package com.zq.datastruct.linkedlist;
import java.util.Arrays;
/**
* Created by zhengshouzi on 2015/11/16.
*/
public class QueueTest {
public static void main(String[] args) {
Queue<Integer> queue =null;
System.out.println("------------------------arrayLinerQueue-------------------------------------");
queue=new ArrayLinerQueue();
queue.enQueue(32);
queue.enQueue(43);
queue.deQueue();
queue.enQueue(98);
System.out.println(queue.toString());
queue.enQueue(444);
System.out.println(queue.toString());
queue.enQueue(444);
System.out.println(queue.toString());
System.out.println("------------------------arrayCycleQueue-------------------------------------");
queue = new ArrayCycleQueue<>();
queue.enQueue(32);
queue.enQueue(43);
queue.deQueue();
queue.enQueue(98);
System.out.println(queue.toString());
queue.enQueue(444);
System.out.println(queue.toString());
queue.enQueue(567);
queue.enQueue(1200);
System.out.println(queue.toString());
System.out.println("------------------------linkedListQueue-------------------------------------");
queue = new LinkedListQueue();
queue.enQueue(32);
queue.enQueue(43);
queue.deQueue();
queue.enQueue(98);
System.out.println(queue.toString());
queue.enQueue(444);
System.out.println(queue.toString());
queue.enQueue(567);
queue.enQueue(1200);
System.out.println(queue.toString());
}
}
隊列應用:
當多個任務分配給打印機時,爲了防止衝突,創建一個隊列,把任務入隊,按先入先出的原則處理任務。
當多個用戶要訪問遠程服務端的文件時,也用到隊列,滿足先來先服務的原則。
現如今衆多的消息中間件的實現就是採用隊列的思想。
……
有一個數學的分支,叫隊列理論(queuing theory )。用來計算 預測用戶在隊中的等待時間,隊的長度等等問題。
答案取決於用戶到達隊列的頻率,用戶的任務的處理時間。如果比較簡單的情況,可以單單用分析解決。一個簡單的例子就是,
一部電話,一個接線員。當一個電話打進來,如果接線員很忙,就電話放到等待線路後。接線員從隊頭開始應答。
凡事一切需要按照順序來處理的數據,都可以用隊列來實現,如果順序帶有優先級,可以用優先隊列
隊列和棧的說明:
隊列比較適合於用鏈表實現:因爲隊列的操作在隊列的兩端進行,使用數組不方便
棧比較適合於用數組實現:而棧的操作始終在棧頂進行,始終在數組頂部操作就好了。