隊列中典型的就是遵循先進先出原則的,隊列是操做受限制的線性表結構。node
1、隊列的特色算法
隊列最大的特色就是先進先出,主要有兩個操做入列和出列。
跟棧同樣,既能夠用數組實現,又能夠用鏈表實現,用數組實現叫順序隊列,用鏈表實現,叫鏈式隊列,特別是一個長的像環的循環隊列。
在數組實現隊列的時候,會有數據搬移操做,要想解決數據搬移的問題,咱們就須要像環同樣的循環隊列。數組
2、基於數組實現的隊列數據結構
1 public class ArrayQueue { 2 3 // 數組:items 數組的大小:n 4 private String[] items; 5 6 private int n = 0; 7 8 // head表示對頭下標 tail表示隊尾下標 9 private int head = 0; 10 11 private int tail = 0; 12 13 /** 14 * 申請一個大小爲capacity的數組 15 * 16 * @param capacity 17 */ 18 public ArrayQueue(int capacity) { 19 this.items = new String[capacity]; 20 this.n = capacity; 21 } 22 23 /** 24 * 入列操做 25 * 26 * @param item 27 * @return 28 */ 29 public boolean enqueue(String item) { 30 // 若是tail == n 表示隊列滿了 31 if (tail == n) { 32 return false; 33 } 34 this.items[tail] = item; 35 ++tail; 36 return true; 37 } 38 39 /** 40 * 出列操做 41 * 42 * @return 43 */ 44 public String dequeue() { 45 // 若是 head == tail 表示隊列爲空 46 if (this.head == this.tail) { 47 return null; 48 } 49 String ret = this.items[head]; 50 ++head; 51 return ret; 52 } 53 54 /** 55 * 隨着不停的入列,出列操做,當tail移動到最後一個數組位置的時候,即便數組中前面還有空餘空間也沒法在隊列中添加數據了,解決這個問題的 56 * 辦法是進行數據搬移,將隊列後面的數據搬移到前面空餘的位置中,改造入隊操做,若空間不足,觸發數據搬移 57 * 58 */ 59 60 /** 61 * 改造以後的入列操做 62 * 63 * @param item 64 * @return 65 */ 66 public boolean enqueue2(String item) { 67 // tail == n 表示隊列中沒有剩餘空間了 68 if (tail == n) { 69 // tail == n && head == 0表示整個隊列都佔滿了 70 if (head == 0) { 71 return false; 72 } 73 // 數據搬移 74 for (int i = head; head < tail; ++i) { 75 this.items[i - head] = this.items[i]; 76 } 77 // 搬移以後從新更新 head tail 向前移動了head距離 78 tail -= head; 79 head = 0; 80 } 81 this.items[tail] = item; 82 ++tail; 83 return true; 84 } 85 86 }
3、基於鏈表實現的隊列this
1 public class QueueBasedOnLinkedList { 2 3 //隊列的隊首 和 隊尾 4 private Node head = null; 5 private Node tail = null; 6 7 /** 8 * 入列操做 9 * 10 * @param value 11 */ 12 public void enqueue(String value){ 13 if(tail == null){ 14 Node newNode = new Node(value, null); 15 head = newNode; 16 tail = newNode; 17 }else{ 18 tail = new Node(value, null); 19 tail.next = tail; 20 } 21 } 22 23 /** 24 * 出列操做 25 * 26 * @return 27 */ 28 public String dequeue(){ 29 if(head == null){ 30 return null; 31 } 32 String value = head.data; 33 head = head.next; 34 if(head == null){ 35 tail = null; 36 } 37 return value; 38 } 39 40 public void printAll(Node node){ 41 while(node != null){ 42 System.out.print(node.data + " "); 43 node = node.next; 44 } 45 System.out.println(); 46 } 47 48 public static class Node{ 49 private String data; 50 private Node next; 51 52 public Node(String data, Node next){ 53 this.data = data; 54 this.next = next; 55 } 56 57 public String getData(){ 58 return this.data; 59 } 60 } 61 }
4、環形隊列spa
1 public class CircularQueue { 2 3 // 數組:items 數組長度:n 4 private String[] items; 5 private int n = 0; 6 7 // head 表示對頭下標 tail表示隊尾下標 8 private int head = 0; 9 private int tail = 0; 10 11 /** 12 * 申請一個大小爲capacity 的數組 13 * 14 * @param capacity 15 */ 16 public CircularQueue(int capacity) { 17 this.items = new String[capacity]; 18 this.n = capacity; 19 } 20 21 /** 22 * 入列操做 23 * 24 * @return 25 */ 26 public boolean enqueue(String item) { 27 // 隊列滿了 28 if ((tail + 1) % n == head) { 29 return false; 30 } 31 this.items[tail] = item; 32 tail = (tail + 1) % n; 33 return true; 34 } 35 36 /** 37 * 出列操做 38 * 39 * @return 40 */ 41 public String dequeue() { 42 // 若是head = tail 表示隊列爲空 43 if (head == tail) { 44 return null; 45 } 46 String ret = items[head]; 47 head = (head + 1) % n; 48 return ret; 49 } 50 51 }
此大部份內容來自極客時間專欄,王爭老師的《數據結構與算法之美》code
極客時間:https://time.geekbang.org/column/intro/126blog