1.題目
設計你的循環隊列實現。 循環隊列是一種線性數據結構,其操作表現基於 FIFO(先進先出)原則並且隊尾被連接在隊首之後以形成一個循環。它也被稱爲“環形緩衝器”。
循環隊列的一個好處是我們可以利用這個隊列之前用過的空間。在一個普通隊列裏,一旦一個隊列滿了,我們就不能插入下一個元素,即使在隊列前面仍有空間。但是使用循環隊列,我們能使用這些空間去存儲新的值。
你的實現應該支持如下操作:
MyCircularQueue(k): 構造器,設置隊列長度爲 k 。
Front: 從隊首獲取元素。如果隊列爲空,返回 -1 。
Rear: 獲取隊尾元素。如果隊列爲空,返回 -1 。
enQueue(value): 向循環隊列插入一個元素。如果成功插入則返回真。
deQueue(): 從循環隊列中刪除一個元素。如果成功刪除則返回真。
isEmpty(): 檢查循環隊列是否爲空。
isFull(): 檢查循環隊列是否已滿。
2. 解答
- 如果循環隊列讀取元素的速度快於存入元素的速度,隊頭front指針很快追上隊尾rear,當rear==front表示隊列爲空
- 如果循環隊列存入元素的速度快於讀取元素的速度,隊尾rear指針很快追上隊頭front,當(rear + 1) % maxSize == front表示隊列已滿
//
// Created by shuxnhs on 18-12-17.
//
#include <iostream>
#include <vector>
using namespace std;
class MyCircularQueue {
protected:
const int maxSize;
vector<int> v;
int front = 0;
int rear = 0;
public:
/** Initialize your data structure here. Set the size of the queue to be k. */
MyCircularQueue(int k) : maxSize(k+1), v(k+1,0){
//循環隊列中最多隻能存放maxSize-1個元素,
//因此初始化要存放k個元素的雙端隊列,必須讓maxSize=k+1
}
/** Insert an element into the circular queue. Return true if the operation is successful. */
//進隊,判斷隊列是否已滿
//將值插入隊尾,隊尾rear向前加1,rear=(rear+1)%maxSize
bool enQueue(int value) {
if(isFull()){
return false;
}else{
v[rear]=value;
rear=(rear+1)%maxSize;
return true;
}
}
/** Delete an element from the circular queue. Return true if the operation is successful. */
// 出隊,判斷隊列是否爲空
// 隊頭向前加1,front=(front+1)%maxSize;
bool deQueue() {
if(isEmpty()){
return false;
} else{
front=(front+1)%maxSize;
return true;
}
}
/** Get the front item from the queue. */
// 獲取隊首的值
int Front() {
if(isEmpty()){
return -1;
} else{
return v[front];
}
}
/** Get the last item from the queue. */
// 輸出隊尾v[(rear+maxSize-1)%maxSize]
int Rear() {
if(isEmpty()){
return -1;
} else{
return v[(rear+maxSize-1)%maxSize];
}
}
/** Checks whether the circular queue is empty or not. */
//如果rear==front表示隊列爲空
bool isEmpty() {
return front == rear;
}
/** Checks whether the circular queue is full or not. */
//如果(rear + 1) % maxSize == front表示隊列已滿
bool isFull() {
return (rear + 1) % maxSize == front;
}
//求雙端隊列中元素的個數(rear-front+maxSize)%maxSize
int getSize(){
return (rear-front+maxSize)%maxSize;
}
};
int main() {
MyCircularQueue myCircularQueue(6);
myCircularQueue.enQueue(1);
myCircularQueue.enQueue(2);
myCircularQueue.enQueue(3);
cout<<myCircularQueue.deQueue();
cout<<myCircularQueue.Front();
cout<<myCircularQueue.Rear();
cout<<myCircularQueue.isEmpty();
cout<<myCircularQueue.isFull();
cout<<myCircularQueue.getSize();
}