First Queue Experience

Queue: Special linear tables that allow insertion of data at one end and deletion of data at the other end only.The end of an insert operation is called the end of the queue and is often called the queue entry; the end of a delete operation is called the queue head and is often called the queue exit.Queues have a FIFO feature.
Queues are divided into sequential and chain queues
A sequential queue means that the storage space allocated to it is continuous

Chained queues are equivalent to our single-chain list

Chained queues are equivalent to our single-chain list, but we need to move the tail pointer when inserting and the head pointer when deleting.
Sequential Queue:

But this is equivalent to header deletion of our order table inserting an element in the head at a time or deleting an element in the head at a time. We all need to move the following elements as a whole, which is extremely inefficient.
Therefore, in our STL containers, there is no header insertion or deletion of the root.And if we use this method to move elements behind the queue forward, it's very inefficient


That wastes our storage space like 0 and 1, but we can't continue inserting because of a false overflow
An overflow of a sequential queue that has storage space left after multiple queue and queue operations but is no longer queued is called a false overflow.
An overflow caused by a sequential queue that is full of maximum storage space and requires queuing operations is called a true overflow.
To solve the problem of false overflow, we introduced a circular queue
For example, the maximum space we allocate to a queue is 6. We can't continue inserting when the queue is in the false overflow shown above. Otherwise, it will cause the program to crash over the bounds, and we are not suitable for expanding capacity directly like a sequential stack because our actual storage space is not exhausted.So the trick is that we can think of this sequential queue as a circular space.We call it a circular queue as shown in the figure

We started by pointing both the head and the end of the queue at the head of this ring queue.
But at this point, it is no longer easy to void and fill a ring queue
Judging this ring queue we can't judge by the queue head==queue tail
Why?
Look at the following picture:

So how can I tell if the queue is empty or full now?

So we have to use other ways to tell if the queue is empty or full
Mode 1:
Less memory unit If less storage space is used, the queue end pointer plus 1 equals the judgment that the head pointer is full: (rear+1)%MaxSize==front Queue empty condition is still back== front

Mode 2:
Set a flag to be marked as flag with initial flag=0; flag=1 whenever a queue entry operation succeeds; flag=0 whenever a queue exit succeeds. The criteria for determining queue empty are: rear = front & & flag == 0; rear = front & & flag=1 when a queue is full

This way you can also tell if the queue is empty or full.

Mode 3:
Set a counter to set the counter count, which is initially set to count=0. Whenever the queue entry operation succeeds, count is added to 1, and whenever the queue exit succeeds, count is subtracted from 1.The criteria for empty queues are count==0; the criteria for full queues are count>0 && rear == front or count == MaxSize
This way of comparing Ghana, but as long as the number of elements we insert equals the maximum storage space, we can directly tell that the current queue is full.
If the number of inserted elements ==0, you can directly tell that the current queue is empty

Specific implementation of circular queues:

#include<iostream>
#include<stdlib.h>
using namespace std;
template<class T>
class Queue
{
public:
    friend std::ostream& operator<< <T>(std::ostream& _cout, const Queue<T>& v);
    Queue(size_t Capacity = 4)
    :_Capacity(Capacity)
    , _Front(0)
    , _Rear(0)
    , _pData(NULL)
    , _Count(0)
    {
        _Capacity += 1;
        _pData = new T[_Capacity];
    }
    ~Queue()
    {
        if (_pData != NULL)
        {
            delete[]_pData;
        }
    }
    void Push(const T &data);
    void Pop();
    int  Size();
    bool Empty();
    int  Front();
    int  Back();
    void Print();
    bool IsFull();
private:
    T* _pData;
    size_t _Capacity;
    size_t _Front;
    size_t _Rear;
    size_t _Count;

};
template<class T>
void Queue<T>::Push(const T &data)
{
    if (_Count!=_Capacity)
    {
        _pData[_Rear] = data;
        _Rear = (_Rear + 1) % _Capacity;
        _Count++;
    }
}
template<class T>
void Queue<T>::Pop()
{
    if (!Empty())
    {
        _Front = (_Front + 1) % _Capacity;
        _Count--;
    }
}
template<class T>
int Queue<T>::Size()
{
    return _Count;
}
template<class T>
bool Queue<T>::IsFull()
{
    return _Count == _Capacity;
}
template<class T>
bool Queue<T>::Empty()
{
    return _Count == 0;
}
template<class T>
int  Queue<T>::Front()
{
    return _pData[Front];
}
template<class T>
int  Queue<T>::Back()
{
    return _pData[Back];
}
template<class T>
void Queue<T>::Print()
{
    for (int i = _Front; i < _Count + _Front; i++)//Note that elements are always printed from the beginning of the queue
    {
        cout << _pData[i%_Capacity] << " ";//It must be ground to its capacity
    }
    cout << endl;
}
template<class T>
ostream& operator<<(ostream& _cout, const Queue<T>& v)
{
    for (int i =v._Front; i < v._Count+v._Front; i++)
    {
        _cout << v._pData[i%(v._Capacity)]<<" ";
    }
    return _cout;
}
void FunTest()
{
    Queue<int>s;
    s.Push(1);
    s.Push(2);
    s.Push(3);
    s.Push(4);
    s.Push(5);
    s.Print();
    cout << s.IsFull() << endl;
    s.Pop();
    cout << s.IsFull() << endl;
    s.Push(6);
    s.Pop();
    s.Pop();
    cout << s;
}
int main()
{
    FunTest();
    system("pause");
    return 0;
}

It is important to note here that when the output operator is overloaded, since I use a template, I must add T to the template parameter list when declaring, otherwise there will be a link error!!!
friend std::ostream& operator<< (std::ostream& _cout, const Queue& v);

Keywords: less

Added by sonicfusion on Sun, 07 Jul 2019 20:02:41 +0300