Skip to main content

Design Circular Queue

Problem statement

Design your implementation of the circular queue. The circular queue is a linear data structure in which the operations are performed based on FIFO (First In First Out) principle and the last position is connected back to the first position to make a circle. It is also called "Ring Buffer".

One of the benefits of the circular queue is that we can make use of the spaces in front of the queue. In a normal queue, once the queue becomes full, we cannot insert the next element even if there is a space in front of the queue. But using the circular queue, we can use the space to store new values.

Implementation the MyCircularQueue class:

  • MyCircularQueue(k) Initializes the object with the size of the queue to be k.
  • int Front() Gets the front item from the queue. If the queue is empty, return -1.
  • int Rear() Gets the last item from the queue. If the queue is empty, return -1.
  • boolean enQueue(int value) Inserts an element into the circular queue. Return true if the operation is successful.
  • boolean deQueue() Deletes an element from the circular queue. Return true if the operation is successful.
  • boolean isEmpty() Checks whether the circular queue is empty or not.
  • boolean isFull() Checks whether the circular queue is full or not.

You must solve the problem without using the built-in queue data structure in your programming language. 

Example 1:

Input["MyCircularQueue", "enQueue", "enQueue", "enQueue", "enQueue", "Rear", "isFull", "deQueue", "enQueue", "Rear"][[3], [1], [2], [3], [4], [], [], [], [4], []]Output[null, true, true, true, false, 3, true, true, true, 4]ExplanationMyCircularQueue myCircularQueue = new MyCircularQueue(3);myCircularQueue.enQueue(1); // return TruemyCircularQueue.enQueue(2); // return TruemyCircularQueue.enQueue(3); // return TruemyCircularQueue.enQueue(4); // return FalsemyCircularQueue.Rear();     // return 3myCircularQueue.isFull();   // return TruemyCircularQueue.deQueue();  // return TruemyCircularQueue.enQueue(4); // return TruemyCircularQueue.Rear();     // return 4

Constraints:

  • 1 <= k <= 1000
  • 0 <= value <= 1000
  • At most 3000 calls will be made to enQueue, deQueueFrontRearisEmpty, and isFull.

My solution

class Node {
constructor(val) {
this.val = val;
this.next = null
}
}

/**
* @param {number} k
*/
var MyCircularQueue = function(k) {
this.head = null;
this.tail = null;
this.maxSize = k;
this.size = 0;
};

/**
* @param {number} value
* @return {boolean}
*/
MyCircularQueue.prototype.enQueue = function(value) {
if (this.size === this.maxSize) {
return false;
}
const newNode = new Node(value);

if (!this.head) {
this.head = newNode;
this.tail = newNode;
newNode.next = this.head;
this.size++
return true;
}

// Make newNode the current tails next node;
this.tail.next = newNode;
this.tail = newNode;
newNode.next = this.head;
this.size++

return true;

};

/**
* @return {boolean}
*/
MyCircularQueue.prototype.deQueue = function() {
if (!this.head) {
return false;
}

const nodeToDelete = this.head;
if (this.head) {
this.size--;
if (this.size === 0) {
this.head = null;
this.tail = null
} else {
this.head = this.head.next;
this.tail.next = this.head;
}
} else {
this.head = null;
this.tail = null
}
return true;
};

/**
* @return {number}
*/
MyCircularQueue.prototype.Front = function() {
if (this.head === null) {
return -1
}
return this.head.val;
};

/**
* @return {number}
*/
MyCircularQueue.prototype.Rear = function() {
if (this.tail === null) {
return -1
}
return this.tail.val
};

/**
* @return {boolean}
*/
MyCircularQueue.prototype.isEmpty = function() {
// console.log("this.size", this.size)
return this.size === 0
};

/**
* @return {boolean}
*/
MyCircularQueue.prototype.isFull = function() {
return this.size === this.maxSize;
};

/**
* Your MyCircularQueue object will be instantiated and called as such:
* var obj = new MyCircularQueue(k)
* var param_1 = obj.enQueue(value)
* var param_2 = obj.deQueue()
* var param_3 = obj.Front()
* var param_4 = obj.Rear()
* var param_5 = obj.isEmpty()
* var param_6 = obj.isFull()
*/