priority_queue優先隊列 按照由小到大順序

C++優先隊列的基本使用方法

 #include<iostream>
#include<functional>
#include<queue>
using namespace std;

struct node
{
    friend bool operator< (node n1, node n2)
    {
        return n1.priority < n2.priority;//"<"爲從大到小排列,">"爲從小打到排列
    }
    int priority;
    int value;
};

int main()
{
    const int len = 5;
    int i;
    int a[len] = {3,5,9,6,2};
    //示例1
    priority_queue<int> qi;//普通的優先級隊列,按從大到小排序
    for(i = 0; i < len; i++)
        qi.push(a[i]);
    for(i = 0; i < len; i++)
    {
        cout<<qi.top()<<" ";
        qi.pop();
    }
    cout<<endl;

    //示例2
    priority_queue<int, vector<int>, greater<int> > qi2;//從小到大的優先級隊列,可將greater改爲less,即爲從大到小
    for(i = 0; i < len; i++)
        qi2.push(a[i]);
    for(i = 0; i < len; i++)
    {
        cout<<qi2.top()<<" ";
        qi2.pop();
    }
    cout<<endl;

    //示例3
    priority_queue<node> qn;//必須要重載運算符
    node b[len];
    b[0].priority = 6; b[0].value = 1;
    b[1].priority = 9; b[1].value = 5;
    b[2].priority = 2; b[2].value = 3;
    b[3].priority = 8; b[3].value = 2;
    b[4].priority = 1; b[4].value = 4;
 
    for(i = 0; i < len; i++)
        qn.push(b[i]);
    cout<<"優先級"<<'\t'<<"值"<<endl;
    for(i = 0; i < len; i++)
    {
        cout<<qn.top().priority<<'\t'<<qn.top().value<<endl;
        qn.pop();
    }
    return 0;
}

對於隊列裏元素爲一個結構體類型,按照某一個屬性排序,就需要對比較函數進行重載

小結一下:

1、若是定義值類型對象,如: 

int 
 main() 
{      
    priority_queue<node> qn;

    node n1; 
    n1.a = 9; 
    node n2; 
    n2.a = 2; 
    node n3; 
    n3.a = 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 的操作符重載函數即可: 

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第三版 中文版中關於操作符重載有如下描述:

"程序員只能爲類類型或枚舉類型的操作數定義重載操作符我們可以這樣來實現把重 
載操作符聲明爲類的成員或者聲明爲名字空間成員同時至少有一個類或枚舉類型的參數 
按值傳遞或按引用傳遞"

因此不可用指針類型的參數;

2、如果想定義一個指針類型的優先隊列,那就不可這麼簡單的定義了,你需要自定義一個自己的比較函數,在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;  
    }  
};  
這樣在main函數中就可以定義指針類型的優先隊列了:

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); /span>


    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)//

也就是沒有找到指針類型的"<"重載,所有不會達到優先隊列的效果。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章