---
# System prepended metadata

title: 622. Design Circular Queue
tags: [C++, LeetCode-Medium]

---

# 622. Design Circular Queue
Difficulty: Medium

## Solution
```cpp=
/**
*** Author: R-CO
*** E-mail: daniel1820kobe@gmail.com
*** Date: 2020-09-12
**/
#include <cstdlib>
#include <iostream>
using namespace std;

#define USE_MSVC 1

#define LINK_LIST_VER 1
#define ARRAY_VER 0

#if USE_MSVC
#include <crtdbg.h>
#endif

#if LINK_LIST_VER

struct Node {
  int value{0};
  Node *next{nullptr};
};

class MyCircularQueue {
 public:
  /** Initialize your data structure here. Set the size of the queue to be k. */
  explicit MyCircularQueue(int k) {
    queue_size_ = k;

    queue_buffer_ = new Node;
    front_ = queue_buffer_;
    rear_ = front_;

    while (--k > 0) {
      queue_buffer_->next = new Node;
      queue_buffer_ = queue_buffer_->next;
    }

    if (queue_buffer_ != nullptr) {
      queue_buffer_->next = front_;
    }
  }

  ~MyCircularQueue() {
    while (queue_size_-- > 0) {
      auto *p = queue_buffer_;
      queue_buffer_ = queue_buffer_->next;
      delete p;
    }
  }

  /** Insert an element into the circular queue. Return true if the operation is
   * successful. */
  bool enQueue(int value) {
    if (isFull()) {
      return false;
    }

    if (!isEmpty()) {
      rear_ = rear_->next;
    }
    is_empty_ = false;
    rear_->value = value;

    return true;
  }

  /** Delete an element from the circular queue. Return true if the operation is
   * successful. */
  bool deQueue() {
    if (isEmpty()) {
      return false;
    }

    if (front_ == rear_) {
      is_empty_ = true;
    } else {
      front_ = front_->next;
    }

    return true;
  }

  /** Get the front item from the queue. */
  int Front() {
    if (isEmpty()) {
      return -1;
    }

    return front_->value;
  }

  /** Get the last item from the queue. */
  int Rear() {
    if (isEmpty()) {
      return -1;
    }

    return rear_->value;
  }

  /** Checks whether the circular queue is empty or not. */
  bool isEmpty() { return is_empty_ && (front_ == rear_); }

  /** Checks whether the circular queue is full or not. */
  bool isFull() { return rear_->next == front_; }

 private:
  bool is_empty_{true};
  int queue_size_{0};
  Node *queue_buffer_{nullptr};
  Node *front_{nullptr};
  Node *rear_{nullptr};
};

#elif ARRAY_VER

class MyCircularQueue {
public:
	/** Initialize your data structure here. Set the size of the queue to be k. */
	explicit MyCircularQueue(int k) {
		buffer_ = new int[k];
		buffer_size_ = k;
	}

	~MyCircularQueue() {
		delete [] buffer_;
	}

	/** Insert an element into the circular queue. Return true if the operation is successful. */
	bool enQueue(int value) {
		if (isFull()) {
			return false;
		}

		rear_index_ = (!is_empty_) ? (rear_index_ + 1) % buffer_size_ : rear_index_;
		buffer_[rear_index_] = value;
		is_empty_ = false;
		return true;
	}

	/** Delete an element from the circular queue. Return true if the operation is successful. */
	bool deQueue() {
		if (is_empty_) {
			return false;
		}

		if (front_index_ == rear_index_) {
			is_empty_ = true;
			return true;
		}

		front_index_ = (front_index_ + 1) % buffer_size_;
		return true;
	}

	/** Get the front item from the queue. */
	int Front() {
		return (!is_empty_) ? buffer_[front_index_] : -1;
	}

	/** Get the last item from the queue. */
	int Rear() {
		return (!is_empty_) ? buffer_[rear_index_] : -1;
	}

	/** Checks whether the circular queue is empty or not. */
	bool isEmpty() {
		return is_empty_;
	}

	/** Checks whether the circular queue is full or not. */
	bool isFull() {
		return (((rear_index_ + 1) % buffer_size_) == front_index_);
	}

private:
	bool is_empty_{ true };
	int *buffer_{ nullptr };
	int front_index_{ 0 };
	int rear_index_{ 0 };
	int buffer_size_{ 0 };
};

#endif

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

int main(int argc, char *argv[]) {
  const int k = 3;
  const int value_1 = 1;
  const int value_2 = 2;
  const int value_3 = 3;
  const int value_4 = 4;

  int ret_int = 0;
  bool ret_bool = false;

  MyCircularQueue *obj = new MyCircularQueue(k);
  ret_bool = obj->enQueue(value_1);  // true
  ret_bool = obj->enQueue(value_2);  // true
  ret_int = obj->Front();            // 1
  ret_int = obj->Rear();             // 2
  ret_bool = obj->isEmpty();         // false
  ret_bool = obj->isFull();          // false

  ret_bool = obj->enQueue(value_3);  // true
  ret_int = obj->Front();            // 1
  ret_int = obj->Rear();             // 3
  ret_bool = obj->isEmpty();         // false
  ret_bool = obj->isFull();          // true

  ret_bool = obj->enQueue(value_4);  // false
  ret_int = obj->Front();            // 1
  ret_int = obj->Rear();             // 3
  ret_bool = obj->isEmpty();         // false
  ret_bool = obj->isFull();          // true

  ret_bool = obj->deQueue();  // true
  ret_int = obj->Front();     // 2
  ret_int = obj->Rear();      // 3
  ret_bool = obj->isEmpty();  // false
  ret_bool = obj->isFull();   // false

  ret_bool = obj->enQueue(value_4);  // true
  ret_int = obj->Front();            // 2
  ret_int = obj->Rear();             // 4
  ret_bool = obj->isEmpty();         // false
  ret_bool = obj->isFull();          // true

  ret_bool = obj->deQueue();  // true
  ret_int = obj->Front();     // 3
  ret_int = obj->Rear();      // 4
  ret_bool = obj->isEmpty();  // false
  ret_bool = obj->isFull();   // false

  ret_bool = obj->deQueue();  // true
  ret_int = obj->Front();     // 4
  ret_int = obj->Rear();      // 4
  ret_bool = obj->isEmpty();  // false
  ret_bool = obj->isFull();   // false

  ret_bool = obj->deQueue();  // true
  ret_int = obj->Front();     // -1
  ret_int = obj->Rear();      // -1
  ret_bool = obj->isEmpty();  // true
  ret_bool = obj->isFull();   // false

  delete obj;

#if USE_MSVC
  _CrtDumpMemoryLeaks();
#endif
  return EXIT_SUCCESS;
}
```

## Result

Success
Details 
Runtime: 52 ms, faster than 63.03% of C++ online submissions for Design Circular Queue.
Memory Usage: 17.1 MB, less than 5.16% of C++ online submissions for Design Circular Queue.

###### tags: `LeetCode-Medium` `C++`
