上一篇文章寫了棧的相關知識,而本文會講一下隊列html
隊列是一種特殊的線性表,在尾部插入(入隊Enqueue),從頭部刪除(出隊Dequeue),和棧的特性相反,存取數據特色是:FIFOjava
public interface Queue<E> extends Collection<E> { boolean add(E e); //添加一條數據到隊尾,成功返回true,不然false boolean offer(E e); //添加一條數據到隊尾,若是隊列滿了,會返回null E remove(); //從隊頭刪除一條數據,若是是空隊列,會發生異常 E poll(); //從隊頭刪除一條數據,若是是空隊列,會返回null E element(); //返回隊頭的數據,若是是空隊列,會發生異常 E peek(); //返回隊頭的數據,若是是空隊列,會返回null }
queue直接繼承Collection,有6個基本方法實現增刪查的功能算法
單向隊列:數組
PS:刪除的數據仍是保存在內存中的,只是不能被訪問,由於front位置移動了數據結構
上圖中第二步,咱們從隊頭front刪除一些數據,而後隊尾因爲插入數據,rear移動到最後,此時沒法插入數據數據結構和算法
爲了不隊列不滿可是不能插入數據的狀況,採用第三步:循環隊列,將隊尾迴繞到隊列開始的位置post
public class MyQueue<E> { private int maxSize; //隊列總大小 private Object[] elementData; //保存數據的數組 private int front; //隊頭 private int rear; //隊尾 private int nItems; //隊列元素的數量 public MyQueue(int value) { maxSize = value; elementData = new Object[value]; front = 0; rear = -1; nItems = 0; } public void add(E e) { if (isFull()) { System.out.println("當前隊列已滿"); } else { if (rear == maxSize - 1) { //若是rear已經指向最後面,將隊尾迴繞到隊列開始的位置 rear = -1; } elementData[++rear] = e; //rear後移一位(首位爲0),而且插入數據 nItems++; //元素數量+1 } } //移除數據 public E remove(){ E temp = null; if (isEmpty()) { System.out.println("當前爲空隊列,沒法刪除"); } else { temp = (E)elementData[front++]; //返回隊頭front的數據,而後front後移一位 if (front == maxSize) { //若是front已經後移到最末尾了,front重置 front = 0; } nItems--; //元素數量-1 } return temp; } public E peek(){ //查看隊頭數據 return (E)elementData[front]; } public boolean isFull(){ return (nItems == maxSize); } public boolean isEmpty(){ return (nItems ==0); } public int getSize(){ //返回隊列的大小 return nItems; } }
public static void main(String[] args) { MyQueue<Integer> queue = new MyQueue<>(5); int i = 0; while (!queue.isFull()) { queue.add(i++); } queue.add(6); //當前隊列已滿,沒法添加了 while (!queue.isEmpty()) { queue.remove(); } }
輸出結果:當前隊列已滿
優先級隊列是比棧和隊列更專用的數據結構,通常狀況下,和浦東隊列同樣,優先級隊列有一個頭部和一個尾部,也是從頭部移除數據。ui
不過優先級隊列中,元素按照關鍵字是有序的。關鍵字最小的元素老是在頭部,元素在插入的時候按照順序插入到合適的位置以確保隊列的順序spa
優先級隊列在程序中也有不少應用,例如:圖的最小生成樹htm
這裏咱們使用簡單數組實現優先級隊列,這種方式比較慢,可是很簡單。優先級隊列通常都是經過隊來實現,在後面會降到
代碼實現:
public class MyPriorityQueue { private int maxSize; //隊列總大小 private Object[] elementData; //保存數據的數組 private int nItems; //隊列元素的數量 public MyPriorityQueue(int value) { maxSize = value; elementData = new Object[value]; nItems = 0; } public boolean add(int e) { //添加元素,關鍵字小的元素在頭部,經過插入排序實現 int j; if (nItems == 0) { elementData[nItems++] = e; } else { j = nItems - 1; while (j >= 0 && e > (int)elementData[j]) { elementData[j+1] = elementData[j]; j--; } elementData[j+1] = e; nItems++; } return true; } //移除數據 public Object remove(){ //刪除一條數據,返回老數據 Object value = elementData[nItems-1]; elementData[nItems-1] = null; nItems--; return value; } public Object peekMin() { //返回優先級最高的元素 return elementData[nItems-1]; } //判斷是否爲空 public boolean isEmpty(){ return (nItems == 0); } //判斷是否滿了 public boolean isFull(){ return (nItems == maxSize); } }
public static void main(String[] args) { MyPriorityQueue queue = new MyPriorityQueue(5); int i = 0; while (!queue.isFull()) { queue.add(i++); } while (!queue.isEmpty()) { System.out.println(queue.peekMin());; queue.remove(); } }
打印結果: 0 1 2 3 4
add()經過插入排序實現,時間複雜度O(N),若是忘記插入排序,能夠參考:Java數據結構和算法(三)--三大排序--冒泡、選擇、插入排序
PS:Queue通常做爲程序的某種實現,而不是用來保存數據
內容參考:<Java數據結構和算法>