队列的用法

队列本质上是一种特殊的线性表,它是在一端(队首)进行删除操作,而在另外一端(队尾)进行插入操作,它要遵循先进先出的规则。
队首(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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 创建工作队列 在内核中创建工作队列的方法有两种: (1)使用INIT_WORK宏: INIT_WORK(&my_work, my_work_func); INIT_WORK宏定义在linux/workqueue.h头文件中,第一个参数是指向work_struct类型的指针,第二个参数是指向工作函数的指针。 (2)使用alloc_workqueue函数: my_wq = alloc_workqueue("my_wq", WQ_UNBOUND, 1); alloc_workqueue函数定义在linux/workqueue.h头文件中,它会返回一个指向workqueue_struct类型的指针,第一个参数是工作队列的名称,第二个参数是工作队列的类型,第三个参数是工作队列中的工作线程数。 2. 定义工作函数 工作函数是在工作队列中执行的函数,它是一个带有一个指向work_struct类型的指针作为参数的函数。工作函数的定义如下: void my_work_func(struct work_struct *work) { //do something } 3. 将工作添加到队列中 将工作添加到队列中的方法有两种: (1)使用schedule_work函数: schedule_work(&my_work); schedule_work函数定义在linux/workqueue.h头文件中,它将一个工作添加到工作队列中,并尝试唤醒工作线程。 (2)使用queue_work函数: queue_work(my_wq, &my_work); queue_work函数定义在linux/workqueue.h头文件中,它将一个工作添加到指定的工作队列中,并尝试唤醒工作线程。 4. 销毁工作队列 当工作队列不再需要时,需要将其销毁。销毁工作队列的方法是使用destroy_workqueue函数: destroy_workqueue(my_wq); destroy_workqueue函数定义在linux/workqueue.h头文件中,它将销毁指定的工作队列,并等待工作队列中的所有工作完成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值