資料結構-佇列(2)-迴圈佇列
阿新 • • 發佈:2018-11-19
迴圈佇列
此前,我們提供了一種簡單但低效的佇列實現。
更有效的方法是使用迴圈佇列。 具體來說,我們可以使用固定大小的陣列
和兩個指標
來指示起始位置和結束位置。 目的是重用
我們之前提到的被浪費的儲存
。
設計你的迴圈佇列實現。 迴圈佇列是一種線性資料結構,其操作表現基於 FIFO(先進先出)原則並且隊尾被連線在隊首之後以形成一個迴圈。它也被稱為“環形緩衝器”。
迴圈佇列的一個好處是我們可以利用這個佇列之前用過的空間。在一個普通佇列裡,一旦一個佇列滿了,我們就不能插入下一個元素,即使在佇列前面仍有空間。但是使用迴圈佇列,我們能使用這些空間去儲存新的值。
你的實現應該支援如下操作:
- MyCircularQueue(k): 構造器,設定佇列長度為 k 。
- Front: 從隊首獲取元素。如果佇列為空,返回 -1 。
- Rear: 獲取隊尾元素。如果佇列為空,返回 -1 。
- enQueue(value): 向迴圈佇列插入一個元素。如果成功插入則返回真。
- deQueue(): 從迴圈佇列中刪除一個元素。如果成功刪除則返回真。
- isEmpty(): 檢查迴圈佇列是否為空。
- isFull(): 檢查迴圈佇列是否已滿。
示例:
MyCircularQueue circularQueue = newMycircularQueue(3); // 設定長度為3 circularQueue.enQueue(1); // 返回true circularQueue.enQueue(2); // 返回true circularQueue.enQueue(3); // 返回true circularQueue.enQueue(4); // 返回false,佇列已滿 circularQueue.Rear(); // 返回3 circularQueue.isFull(); // 返回true circularQueue.deQueue(); // 返回true circularQueue.enQueue(4); // 返回true circularQueue.Rear(); // 返回4
提示:
- 所有的值都在 1 至 1000 的範圍內;
- 運算元將在 1 至 1000 的範圍內;
- 請不要使用內建的佇列庫。
在迴圈佇列中,我們使用一個陣列
和兩個指標(head
和 tail
)。 head
表示佇列的起始位置,tail
表示佇列的結束位置。
這裡我們提供了程式碼供你參考:
1 package queue; 2 3 public class Main2 { 4 public static void main(String[] args) { 5 /** 6 * Your MyCircularQueue object will be instantiated and called as such: 7 * MyCircularQueue obj = new MyCircularQueue(k); 8 * boolean param_1 = obj.enQueue(value); 9 * boolean param_2 = obj.deQueue(); 10 * int param_3 = obj.Front(); 11 * int param_4 = obj.Rear(); 12 * boolean param_5 = obj.isEmpty(); 13 * boolean param_6 = obj.isFull(); 14 */ 15 } 16 } 17 18 class MyCircularQueue { 19 20 private int[] data; 21 private int head; 22 private int tail; 23 private int size; 24 25 /** Initialize your data structure here. Set the size of the queue to be k. */ 26 //在這裡初始化資料結構。將佇列的大小設定為k. 27 public MyCircularQueue(int k) { 28 data = new int[k]; 29 head = -1; 30 tail = -1; 31 size = k; 32 } 33 34 /** Insert an element into the circular queue. Return true if the operation is successful. */ 35 //在迴圈佇列中插入一個元素。如果操作成功,返回true。 36 public boolean enQueue(int value) { 37 if (isFull() == true) { 38 return false; 39 } 40 if (isEmpty() == true) { 41 head = 0; 42 } 43 tail = (tail + 1) % size; 44 data[tail] = value; 45 return true; 46 } 47 48 /** Delete an element from the circular queue. Return true if the operation is successful. */ 49 //從迴圈佇列中刪除一個元素。如果操作成功,返回true。 50 public boolean deQueue() { 51 if (isEmpty() == true) { 52 return false; 53 } 54 if (head == tail) { 55 head = -1; 56 tail = -1; 57 return true; 58 } 59 head = (head + 1) % size; 60 return true; 61 } 62 63 /** Get the front item from the queue. */ 64 //從佇列中獲取前面的項 65 public int Front() { 66 if (isEmpty() == true) { 67 return -1; 68 } 69 return data[head]; 70 } 71 72 /** Get the last item from the queue. */ 73 //從佇列中獲取最後一個條目。 74 public int Rear() { 75 if (isEmpty() == true) { 76 return -1; 77 } 78 return data[tail]; 79 } 80 81 /** Checks whether the circular queue is empty or not. */ 82 //檢查迴圈佇列是否為空。 83 public boolean isEmpty() { 84 return head == -1; 85 } 86 87 /** Checks whether the circular queue is full or not. */ 88 //檢查迴圈佇列是否已滿。 89 public boolean isFull() { 90 return ((tail + 1) % size) == head; 91 } 92 } 93 94 /** 95 * Your MyCircularQueue object will be instantiated and called as such: 96 * MyCircularQueue obj = new MyCircularQueue(k); 97 * boolean param_1 = obj.enQueue(value); 98 * boolean param_2 = obj.deQueue(); 99 * int param_3 = obj.Front(); 100 * int param_4 = obj.Rear(); 101 * boolean param_5 = obj.isEmpty(); 102 * boolean param_6 = obj.isFull(); 103 */