Cpp的队列(Queue)学习笔记

Cpp的队列(Queue)学习笔记


队列是一种先入先出(First In First Out)的数据结构,它的实现用两个整型变量(Head、tail一个存储数据的数组(Date[Num]来实现的。

自定义的数据结构体:
struct queue{
int date[Num];
int head;
int tail;
};

这里要注意的是结构体内定义的是类型和变量空间,所以最好不要在结构体内初始化

队列的操作总共有三种:

一、入列操作:

q.date[tail] = x;
tail++;

二、出列操作:

x = q.date[head];
head++;

三、判断非空操作:

head<tail;
STL(Queue)

C++语言的STL中自带了queue的数据结构类型

Queue的模板类封装在头文件中
Queue模板类需要两个参数,一个是元素类型,一个是容器类型
(元素类型书必要的,容器类型是可选的,默认为deque类型)

一、队列对象的定义:

queue< int > q1;
queue< double > q2;

二、队列对象的操作:

  1. 入队:

    q.push(x);   // 将x放入队列的尾部
    
  2. 出列:

    q.pop;      // 弹出队列的头部数据
    
  3. 非空判断:

    q.empty();      // 判断操作的返回值
    
  4. 访问队首元素:

    q.front();      // 得到返回值
    
  5. 访问队尾元素:

    q.back();       // 得到返回值
    
  6. 访问队列中的元素个数:

    q.size();       // 返回元素个数的整型值
    

三、Priority_queue(优先队列)

<queue>的头文件中,除了queue这个模板类之外,还定义了另外一个模板类priority_queue(优先队列)

优先队列和队列的区别在于优先队列不是按照队列入队的顺序出队,而是按照队列中元素的优先权顺序来出队(默认为大者优先,也可以通过指定算子来指定自己的优先顺序)。

priority_queue模板类有三个参数:第一个是元素类型,第二个是容器类型,第三个是比较算子。其中后两个参数都可以省略,默认容器为vector,默认算子为less,即小的往前排,大的往后排(出队时序列尾的元素出队)。

  1. 定义priority_queue对象:

    priority_queue< int > q1;
    priority_queue< pair<int, int> > q2; // 注意在两个尖括号之间一定要留空格。
    priority_queue<int, vector<int>, greater<int> > q3; // 定义小的先出队
    

    priority_queue 的基本操作和 queue 基本相同

    初学者在使用priority_queue时,最困难的可能就是如何定义比较算子了。 如果是基本数据类型,或已定义了比较运算符的类,可以直接用STL的less算子和greater 算子——默认为使用less算子,即小的往前排,大的先出队。 如果要定义自己的比较算子,方法有多种,这里介绍其中的一种:重载比较运算符。优先队 列试图将两个元素x 和y 代入比较运算符(对less算子,调用x<y,对greater算子,调用x>y), 若结果为真,则x 排在y 前面,y 将先于x 出队,反之,则将y 排在x 前面,x 将先出队。 看下面这个简单的示例:

    #include <iostream>
    #include <queue>
    using namespace std;
    class T
    {
    public:
    int x, y, z;
    T(int a, int b, int c):x(a), y(b), z(c)
    {
    }
    };
    bool operator < (const T &t1, const T &t2)
    {
    return t1.z < t2.z; // 按照z 的顺序来决定t1 和t2 的顺序
    }
    main()
    {
    priority_queue<T> q;
    q.push(T(4,4,3));
    q.push(T(2,2,5));
    q.push(T(1,5,4));
    q.push(T(3,3,6));
    while (!q.empty())
    {
    T t = q.top(); q.pop();
    cout << t.x << " " << t.y << " " << t.z << endl;
    }
    return 1;
    }
    

    输出结果为(注意是按照z 的顺序从大到小出队的):

     3 3 6
     2 2 5
     1 5 4
     4 4 3
    

    再看一个按照z 的顺序从小到大出队的例子:

    #include <iostream>
    #include <queue>
    using namespace std;
    class T
    {
    public:
    int x, y, z;
    T(int a, int b, int c):x(a), y(b), z(c)
    {
    }
    };
    bool operator > (const T &t1, const T &t2)
    {
    return t1.z > t2.z;
    }
    main()
    {
    priority_queue<T, vector<T>, greater<T> > q;
    q.push(T(4,4,3));
    q.push(T(2,2,5));
    q.push(T(1,5,4));
    q.push(T(3,3,6));
    while (!q.empty())
    {
    T t = q.top(); q.pop();
    cout << t.x << " " << t.y << " " << t.z << endl;
    }
    return 1;
    }
    

    输出结果为:

    4 4 3
    1 5 4
    2 2 5
    3 3 6
    

    如果我们把第一个例子中的比较运算符重载为:

     bool operator < (const T &t1, const T &t2)
     {
        return t1.z > t2.z; // 按照z 的顺序来决定t1 和t2 的顺序
     }
    

    则第一个例子的程序会得到和第二个例子的程序相同的输出结果。

版权声明:本文为博主原创文章,未经博主允许不得转载。By PengCoX ( Pengc825@foxmail.com )

posted @ 2015-08-05 10:35  CoffeeXC  阅读(1021)  评论(0编辑  收藏  举报