队列

来源:互联网 发布:最强大脑 周玮 知乎 编辑:程序博客网 时间:2024/05/29 04:49

队列

joj上的宽度优先搜索的题我已经做完了,我觉得我应该对队列做一些总结了。我觉得宽度优先搜索与队列的结合,无非有三种情况。

第一种:就是用普通的队列来解答,这类问题往往是每走一步增加相同的权重从而只要用普通队列就可以按权重大小将所有的点一次入队。

第二种:就是用优先队列来解答,这类问题往往一个特点就是在一些特殊的点上权重要比其他一般的点的权重稍大或者稍小一点。从而加入这些点之后使得队列的顺序打乱从而需要对每个点赋予优先级。使优先级高的点先出队列。

第三种:可以说是一种特殊的使用普通队列的一种情况吧。这类问题一般跟某些点有关,一般是从某些点到某些点不会在增加新的权重这些情况一般优先队列是无法解决的。因为优先队列在访问某些点之后是需要把这个点所有能到达的点依次入队,然而在入队的过程中对某些点增加了权重,但是这些点通过走其他的点完全可以不增加权重从而使问题得不到解决。

因此用一种特殊的队列就是把那些可以不必增加权重的点先入队。

下面再说一说队列的库函数吧:

普通队列:

先包含头文件#include<queue>,加上using namesapace std;

在头文件中class queue 的定义:

namespace std

{

         template<classT,class container=deque<T>>

         classqueue;

}

第一个template参数代表元素类别。带有默认值的第二个template参数用来定义queue内部存放元素用的实际容器。缺省时候采用deque。

其中有6个库函数:

1.      empty(); 这个函数的目的在于判断队列是否为空。如果为空则返回true,否则返回false。

2.      front();这个函数的目的在于返回首先入队的元素,但是不会将原来的元素删除。

3.      back(); 这个函数的目的在于返回最后进入队列的元素,但是不会将原来的元素删除。

4.      pop(); 这个函数的目的在于将队列的首元素删除没有返回值。

5.      size(); 这个函数的目的在于返回队列的元素个数.

6.      push();这个函数的目的在于将元素压入队列之中

优先队列:

先包含头文件#include<priority_queue> 加上 using namespacestd;

在头文件中class priority_queue的定义:

namespace std

{

         template<class T,

class container=vector<T>,

class compare=less<typename container::value_type>>

         classpriority_queue;

}

第一个template参数是元素类别,带有默认值的第二个template参数定义了priority_queue内部用来存放元素的容器。缺省容器是vector。带有默认值的第三个template参数定义出“用以搜索下一个最高优先级元素”的排序标准。缺省情况下是以operator<最为比较标准。

例如定义:

priority_queue<int>;

priority_queue<int ,vector<int >,cmp>q;

注意:因为优先队列的库函数需要用到堆operator<目的在于子节点小于父节点因此所谓的下一个元素实际上是“数值最大的元素”。还有就是第三个元素是一个类不是一个函数,因此在定义的时候实际上定义的是个类。

如:

class Node;

class cmp

{

Public:

         booloperator()(const Node &node1,const Node &node2)

         {

                   return(node1.value<node2.value);

         }

}

这里需要注意的是排序标准需要在类中重载括号();

这里重载为什么是()我一直很纳闷,知道今天我看了看库函数的实现细节才知道为什么是()。

实现细节如下:

template<typename _Arg1, typename _Arg2, typename _Result>
    struct binary_function
    {
      typedef _Arg1 first_argument_type;   ///< the type of the first argument
                                           ///  (no surprises here)


      typedef _Arg2 second_argument_type;  ///< the type of the second argument
      typedef _Result result_type;         ///< type of the return type
    };


template<typename T1, typename T2>
  struct less : std::binary_function<T1, T2, bool>
  {
    bool
    operator()(const T1& t1, const T2& t2) const
    { return t1 < t2; }


    bool
    operator()(const T2& t2, const T1& t1) const
    { return t2 < t1; }
  };


// Partial specialization for one type. Same as std::less.
template<typename _Tp>
struct less<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, bool>
  {
    bool
    operator()(const _Tp& __x, const _Tp& __y) const
    { return __x < __y; }
  };


template<typename _Tp>
    struct greater : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x > __y; }
    };


当然也可以直接重载<,>但是必须将函数重载为友元函数

其中的库函数跟普通队列的库函数差不多。主要有:

1.empty() 如果优先队列为空,则返回真

2.pop() 删除第一个元素

3.push() 加入一个元素

4.size() 返回优先队列中拥有的元素的个数

5.top() 返回优先队列中有最高优先级的元素