zoukankan      html  css  js  c++  java
  • 优先级队列的总结

    优先级队列是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素

    每个元素的优先级根据问题的要求而定。当从优先级队列中删除一个元素时,可能出现多个元素具有相同的优先权。在这种情况下,把这些具有相同优先权的元素视为一个先来先服务的队列,按他们的入队顺序进行先后处理。

    优先队列是一种常用的数据结构,通常用堆实现也可以用其他方式实现。 
    对应于大顶堆和小顶堆,存在最大优先队列和最小优先队列。以最大优先队列为例,优先队列除了具有堆上的一些操作,如调整堆, 构建堆之外,还有获得优先队列的最大元素,抽取出优先队列的最大元素,向优先队列中插入一个元素和增大优先队列中某个元素的值。 

    一个优先队列声明的基本格式是: 
    priority_queue<结构类型> 队列名; 

    如果默认的话,是less排序。

    priority_queue <node> q;
    //node是一个结构体
    //结构体里重载了‘<’小于符号
    priority_queue <int,vector<int>,greater<int> > q;
    //不需要#include<vector>头文件
    //注意后面两个“>”不要写在一起,“>>”是右移运算符
    priority_queue <int,vector<int>,less<int> >q;
    q.size();//返回q里元素个数
    q.empty();//返回q是否为空,空则返回1,否则返回0
    q.push(k);//在q的末尾插入k
    q.pop();//删掉q的第一个元素
    q.top();//返回q的第一个元素
    q.back();//返回q的末尾元素

    如果对于队列里元素是一个结构体类型,按照某一个属性排序,就需要对比较函数进行重载

    定义优先级的时候,直接在类中写个friend 的操作符重载函数即可: 

    class  node   
    {   
    public :   
         int  a;  
        node(){}   
        node( int  x):a(x){}   
    friend   bool  operator<( const  node ne1, const  node ne2)//参数也可以为引用,值传递   
        {   
             if (ne1.a > ne2.a)   
            {   
                 return   true ;   
            }   
             else   
            {   
                 return   false ;   
            }   
        }   
    };   

    其中在c++primer第三版 中文版中关于操作符重载有如下描述:"程序员只能为类类型或枚举类型的操作数定义重载操作符我们可以这样来实现把重载操作符声明为类的成员或者声明为名字空间成员同时至少有一个类或枚举类型的参数按值传递或按引用传递"因此不可用指针类型的参数

    如果想定义指针类型的优先队列,则需要另外你需要自定义一个自己的比较函数,在priority_queue的模板函数中,我们可以利用这样一个template<class _Ty, class _Container = vector<_Ty>, class _Pr = less<typename _Container::value_type> >模板,在我们的程序代码中,则需要自己定义一个类来定义第三个模板参数,如:

    class  nodePointerComparer  
    {  
    public :  
        nodePointerComparer(){}  
         bool  operator ()( const  node* ne1,  const  node* ne2)  const   
        {  
             return  ne1->lessthan(ne2);  
        }  
    };  

    当然在这之前我们的类Node要重新书写 

    class  node  
    {  
    public :  
         int  a;  
        node(){}  
        node( int  x):a(x){} 
    
         bool  lessthan( const  node* pnode)  const   
        {  
             return  a < pnode->a;  
        }  
    };  
    int  main()  
    {  
        priority_queue <node*, vector <node*>, nodePointerComparer> qn;  
        node *n1 =  new  node(90);  
        node *n2 =  new  node(2);  
        node *n3 =  new  node(50); 
    
        qn.push(n1);  
        qn.push(n2); 
        qn.push(n3); 
         int  size = qn.size();  
         for ( int  i = 0; i < size; i++)  
        {  
            cout << qn.top()->a << endl;  
            qn.pop();  
        }  
         return  0; 
    
    }  

    疑问之处:如果你使用第一种值传递的操作符重载,来实现第二种的指针类型优先队列,是不会达到想要的结果的,个人理解是因为在指针类型的优先队列中找“<”运算符的时候,重载的不是我们写的值传递friend bool operator<(const node ne1,const node ne2)//

    也就是没有找到指针类型的"<"重载,所有不会达到优先队列的效果。

  • 相关阅读:
    冲刺的二阶段第五天
    第二阶段冲刺第四天
    冲刺第二阶段第三天
    《你的灯亮着吗》读书笔记三
    《你的灯亮着吗》读书笔记二
    《你的灯亮着吗》读书笔记一
    数1
    水王续
    输入法之体验
    返回一个二维整数数组中最大联通子数组的和
  • 原文地址:https://www.cnblogs.com/mini-coconut/p/9311267.html
Copyright © 2011-2022 走看看