队列的用法

来源:互联网 发布:网页怎么连接数据库 编辑:程序博客网 时间:2024/06/06 03:27

队列本质上是一种特殊的线性表,它是在一端(队首)进行删除操作,而在另外一端(队尾)进行插入操作,它要遵循先进先出的规则。
队首(front) :允许进行删除的一端称为队首。
队尾(rear) :允许进行插入的一端称为队尾。
这里写图片描述
队列有两种数据存储方式:1、顺序存储结构(静态队列,用数组实现,地址是连续的)。2、链式存储结构(动态队列,用动态链表实现,地址是不连续的)。
一、队列的基本操作:
queue 模板类的定义在头文件中。
与stack 模板类很相似,queue 模板类也需要两个模板参数,一个是元素类型,一个容器类
型,元素类型是必要的,容器类型是可选的,默认为deque 类型。
定义queue 对象的示例代码如下:
queue q1;
queue q2;

queue 的基本操作有:
入队,如例:q.push(x); 将x 接到队列的末端。
出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
访问队首元素,如例:q.front(),即最早被压入队列的元素。
访问队尾元素,如例:q.back(),即最后被压入队列的元素。
判断队列空,如例:q.empty(),当队列空时,返回true。
以下是queue最基本的用法:

#include <cstdlib>#include <iostream>#include <queue>using namespace std;int main(){    int e,n,m;    queue<int> q1;    for(int i=0;i<10;i++)       q1.push(i);    if(!q1.empty())    cout<<"dui lie  bu kong\n";    n=q1.size();    cout<<n<<endl;    m=q1.back();    cout<<m<<endl;    for(int j=0;j<n;j++)    {       e=q1.front();       cout<<e<<" ";       q1.pop();    }    cout<<endl;    if(q1.empty())    cout<<"dui lie  bu kong\n";    system("PAUSE");    return 0;}

顺序存储结构:这种结构事先要基本确定队列的大小,不支持动态分配存储空间,所以插入和删除元素比较省时,但是会造成空间的浪费。为了节省空间,这里引入了循环队列,本质上也是顺序存储结构。

链式存储结构:可以不需要事先知道队列的大小,支持动态和释放空间,但是插入和删除操作比较耗时,也称链队列。

建议:当事先基本上确定队列的大小,且插入和删除操作比较频繁时,优先考虑循环队列。。
1.循环队列实现:
头文件声明和定义放一块了,只实现了基本的操作,不是很完善,等看了源码再改。。

头文件:在Queue.h头文件中

#ifndef QUEUE_H#define QUEUE_H#include<cassert>#include<iostream>using namespace std;template<typename T>class Queue{public:    Queue(int maxsize = 10);    Queue(const Queue<T>& rhs);    Queue<T>& operator=(const Queue<T>& rhs);    ~Queue();public:    bool empty() const;    bool IsFull() const;    int size() const;    void push(const T& data);    void pop();    T& front();    T   front() const;    T& back();    T   back() const;private:    T *array;    int Front;    int rear;    int capacity;};template<typename T>Queue<T>::Queue(int maxsize) :Front(0), rear(0),capacity(maxsize){    array = new T[maxsize];    assert(array != NULL);    //存储分配失败则退出;}template<typename T>Queue<T>::Queue(const Queue<T>& rhs) :Front(rhs.Front), rear(rhs.rear),capacity(rhs.capacity){    array = new T[capacity];    for (int i = 0; i != (this->size()); i++)        array[i] = rhs.array[i];}template<typename T>Queue<T>& Queue<T>::operator=(const Queue<T>& rhs){    if (this != &rhs)    {        delete[] array;        capacity = rhs.capacity;        Front = rhs.Front;        rear = rhs.rear;        array = new T[capacity];        for (int i = 0; i != (this->size()); i++)            array[i] = rhs.array[i];    }    return *this;}template<typename T>Queue<T>::~Queue(){        delete[] array;}template<typename T>bool Queue<T>::empty() const{    return Front == rear;      //此处为循环队列,当front==rear时为空。}template<typename T>bool Queue<T>::IsFull() const{    return(rear + 1) % capacity == Front;   //当(rear+1)%capacity==front为满,因为为满时差一个元素,但是可能rear>front,也可能rear<front.}template<typename T>int Queue<T>::size() const{    return (rear - Front + capacity) % capacity;}template<typename T>void Queue<T>::push(const T& data){    if (!IsFull())    {        array[rear] = data;        rear = (rear + 1) % capacity;    }    else                                                  //当队列满了之后可进行扩容    {        T *newarray=new T[ 2*capacity ];        for (int i = 0; i != 2*capacity&&!this->empty(); i++)        {            newarray[i] =this-> front();            this->pop();        }        delete [ ] array;        array = newarray;        Front = 0;        array[rear] = data;        rear =this->rear+1;        capacity = 2*capacity;    }}template<typename T>void Queue<T>::pop(){    if (!empty())    {        //array[Front].~T();   //将队头元素析构掉        Front = (Front + 1) % capacity;    }    else        cout<<"empty queue!"<<endl;}template<typename T>T& Queue<T>::front(){    if (empty())        cerr << "Error, queue is empty!";    return array[Front];}template<typename T>T Queue<T>::front() const{    if (empty())        cerr << "Error, queue is empty!";    return array[Front];}template<typename T>T& Queue<T>::back(){    if (empty())        cerr << "Error, queue is empty!";    return array[rear-1];                             //rear类似与尾后指针}template<typename T>T Queue<T>::back() const{    if (empty())        cerr << "Error, queue is empty!";    return array[rear-1];}#endif // QUEUE_H

测试代码:

网上找的代码:

#include<iostream>#include"Queue.h"using namespace std;int main(){    Queue<int> q(10); //声明队列    int n;    cin >> n;    for (int i = 0; i<n; i++)        q.push(i + 1);    while (!q.empty())    {        cout << q.front() << " ";        q.pop();        if (!q.empty()) //此处需要判断此时队列是否为空        {            q.push(q.front());            q.pop();        }    }    cout << endl;    return 0;}

2.链队列的实现:

头文件:

在Queue1.h头文件中

#ifndef QUEUE_H1#define QUEUE_H1/**********在队头删除节点,队尾添加节点*************/#include<iostream>using namespace std;template<typename T>class Queue{public:    Queue();    ~Queue();    bool empty() const;    int size() const;    void clear();    void push(const T & node);    void pop();    T&  front();    T   front() const;private:       //也可以直接用来链表list直接构造    struct  QueueNode    {        T data;        QueueNode* next;        QueueNode(const T& Newdata, QueueNode* nextnode=NULL) :data(Newdata), next(nextnode)        { }       // QueueNode() = default;    };    QueueNode * Front;  //队头指针    QueueNode * rear;  // 队尾指针    int count;};//此处不设头节点template<typename T>Queue<T>::Queue() :Front (NULL),  rear (NULL), count(0){}template<typename T>Queue<T>::~Queue(){    clear();}template<typename T>void Queue<T>::push(const T & node){    if(Front==NULL)        Front=rear=new QueueNode(node);    else    {     QueueNode * newqueuenode = new QueueNode(node);    rear->next = newqueuenode;    rear = newqueuenode;    }    count++;}template<typename T>bool Queue<T>::empty() const{    return Front==NULL;}template<typename T>int Queue<T>::size() const{    return count;}template<typename T>void Queue<T>::clear(){    while (Front)    {        QueueNode * FrontofQueue = Front;        Front = Front->next;        delete FrontofQueue;    }    count = 0;}template<typename T>void Queue<T>::pop(){    if (empty())    {        cerr << "Error, queue is empty!";    }    QueueNode * FrontofQueue = Front;    Front = Front->next;    delete FrontofQueue;    count--;}template<typename T>T& Queue<T>::front(){    if (empty())    {        cerr << "Error, queue is empty!";    }    return Front->data;}template<typename T>T Queue<T>::front() const{    if (empty())    {        cerr << "Error, queue is empty!";    }    return Front->data;}#endif // QUEUE_H1

测试代码:

#<iostream>#include"Queue1.h"using namespace std;int main(){    Queue<int> q; //声明队列    int n;    cin >> n;    for (int i = 0; i<n; i++)        q.push(i + 1);    while (!q.empty())    {        cout << q.front() << " ";        q.pop();        if (!q.empty()) //此处需要判断此时队列是否为空        {            q.push(q.front());            q.pop();        }    }    cout << endl;    return 0;}
原创粉丝点击