leetcode622. Design cyclic queue

Design your circular queue implementation. Circular queue is a linear data structure, the operation performance based on FIFO (First In First Out) principle and is connected to the tail after the head of the queue to form a loop. It is also known as a "ring buffer."

One of the benefits circular queue is used before we can use this queue space. In a normal queue, once a queue is full, we can not insert the next element, even if there is still space in the front of the queue. However, the use of circular queue, we can use the space to store the new value.

You should support the implementation of the following operations:

MyCircularQueue (k): constructor, set queue length to be k.
Front: get elements from the first team. If the queue is empty, return -1.
Rear: get the tail elements. If the queue is empty, return -1.
enQueue (value): Insert an element to the circular queue. Returns true if successful insertion.
deQueue (): removes an element from the circular queue. Returns true if successfully deleted.
isEmpty (): Check whether the circular queue is empty.
isFull (): Check whether the circular queue is full

A) circular queue
design of a circular queue, the data key is to maintain the invariants in the operation, i.e., to maintain the proper relationship between the object properties.
(1) the constructor define four attributes:
self._len: queue length
listing for recording cycle queue elements: self._elems
self._head: index of the first element in the queue
self._num: queue element number
(2) into a queue
added in the tail of the queue element, and is added self._num 1, to maintain the proper relationship between the object properties.
(3) a queue
just after the subject of a pointer to the next column of the first shift element 1, while self._num minus 1.
Remaining operations readily understood, the following code can be found.
(4) obtaining first queue element
if the queue is empty, i.e. self._num equal to 0, return -1; otherwise, returns the element in the index self._head
(5) acquires a queue tail element
when to empty, return -1 ; otherwise, returns the index (self._head + self._num - 1)% self._len elements, the reason for performing a modulo operation, because the circular queue is a list of columns, the last element of the queue storage location a position for the first position
(6) queue is empty
self._num 0
(7) the queue is full
self._num equal self._len

class MyCircularQueue {
public:
    /** Initialize your data structure here. Set the size of the queue to be k. */
    vector<int> q;
    int p_start,num,fullNum;
    MyCircularQueue(int k) {
        p_start=0;
        num=0;
        fullNum=k;
        for(int i=0;i<k;i++)
            q.push_back(0);
    }
    
    /** Insert an element into the circular queue. Return true if the operation is successful. */
    bool enQueue(int value) {
        if(!isFull())
        {
           q[(num+p_start)%fullNum]=value;
            num++;
            return true;
        }
        return false;
    }
    
    /** Delete an element from the circular queue. Return true if the operation is successful. */
    bool deQueue() {
        if(isEmpty())
            return false;
        else
        {
            p_start=(p_start+1)%fullNum;
            num--;
            return true;
        }
    }
    
    /** Get the front item from the queue. */
    int Front() {
        if(isEmpty())
            return -1;
        else
            return q[p_start];
    }
    
    /** Get the last item from the queue. */
    int Rear() {
        if(isEmpty())
            return -1;
        else
        {
            return q[(num-1+p_start)%fullNum];
        }
    }
    
    /** Checks whether the circular queue is empty or not. */
    bool isEmpty() {
        return num==0;
    }
    
    /** Checks whether the circular queue is full or not. */
    bool isFull() {
        return num==fullNum;
    }
};

 The following official solution, feeling good understanding ..................

class MyCircularQueue {
private:
    vector<int> data;
    int head;
    int tail;
    int size;
public:
    /** Initialize your data structure here. Set the size of the queue to be k. */
    MyCircularQueue(int k) {
        data.resize(k);
        head = -1;
        tail = -1;
        size = k;
    }
    
    /** Insert an element into the circular queue. Return true if the operation is successful. */
    bool enQueue(int value) {
        if (isFull()) {
            return false;
        }
        if (isEmpty()) {
            head = 0;
        }
        tail = (tail + 1) % size;
        data[tail] = value;
        return true;
    }
    
    /** Delete an element from the circular queue. Return true if the operation is successful. */
    bool deQueue() {
        if (isEmpty()) {
            return false;
        }
        if (head == tail) {
            head = -1;
            tail = -1;
            return true;
        }
        head = (head + 1) % size;
        return true;
    }
    
    /** Get the front item from the queue. */
    int Front() {
        if (isEmpty()) {
            return -1;
        }
        return data[head];
    }
    
    /** Get the last item from the queue. */
    int Rear() {
        if (isEmpty()) {
            return -1;
        }
        return data[tail];
    }
    
    /** Checks whether the circular queue is empty or not. */
    bool isEmpty() {
        return head == -1;
    }
    
    /** Checks whether the circular queue is full or not. */
    bool isFull() {
        return ((tail + 1) % size) == head;
    }
};

/**
 * 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();
 */

 

Guess you like

Origin www.cnblogs.com/renzmin/p/11889582.html