http://blog.csdn.net/liuzhanchen1987/article/details/7856893
優先級隊列區別於普通隊列的一點是:優先級隊列如果插入的節點是結構體類型,則要在結構體中重載比較操作符函數。
示例代碼如下:
//優先級隊列的使用測試
//優先級隊列跟對列的使用方式的區別是優先級隊列在插入元素時
//在將元素插入隊尾後還要根據比較值對該元素進行位置的調整
#include<iostream>
#include<queue>
using namespace std;
struct Node
{
int key;
char ch;
//只有<重載操作符函數時,如果將<改爲>爲什麼不行,出現error C2784的錯誤
friend bool operator <(Node node1,Node node2)
{
//<爲從大到小排列,>爲從小到大排列
return node1.key<node2.key;
}
friend bool operator >(Node node1,Node node2)
{
return node1.key<node2.key;
}
};
int main()
{
//對於優先隊列中包含結構體或者類的類型,該結構體或者類必須包含比較操作符的重載
//因爲優先級隊列在插入時,是按照結構體中的某一個元素進行比較,如果
//不重載比較操作符,優先級隊列比較的是結構體,而我們知道結構體是無法直接進行比較的。
//如下定義優先級隊列qu,less表示按照遞減的順序插入元素,換成greater則表示按照遞增的
//方式插入元素
priority_queue<int,vector<int>,less<int> >qu;
//定義如下的que優先級隊列,會默認按照從大到小對插入元素進行排列
//所以在沒有定義<時,會出現錯誤
priority_queue<Node>que;
priority_queue<Node,vector<Node>,less<Node> >qe;
Node node[10];
int i;
int a[10]={4,2,1,3,6,8,7,9,10,5};
char b[10]={'a','b','c','d','e','f','g','h','i','j'};
//從大到小插入元素
for(i=0;i<10;i++)
{
qu.push(a[i]);
}
for(i=0;i<10;i++)
{
cout<<qu.top()<<endl;
qu.pop();
}
cout<<endl;
//默認從大到小插入元素
for(i=0;i<10;i++)
{
node[i].key=a[i];
node[i].ch=b[i];
que.push(node[i]);
}
for(i=0;i<10;i++)
{
cout<<que.top().key<<" "<<que.top().ch<<endl;
que.pop();
}
cout<<endl;
//利用了priority_queue<Node,vector<Node>,less<Node>>qe;這個定義後可以
//將元素從大到小插入元素,但是注意的是結構體中必須重載<操作符,不然會出錯
for(i=0;i<10;i++)
{
node[i].key=a[i];
node[i].ch=b[i];
qe.push(node[i]);
}
for(i=0;i<10;i++)
{
cout<<qe.top().key<<" "<<qe.top().ch<<endl;
qe.pop();
}
return 0;
}
疑問解答:在編寫代碼的時候,在只有一個重載操作符函數<時,我們將<改爲>,que.push(node),出錯,錯誤代號是:C2784.後來發現原因是:我們如下定義的que, priority_queue<Node>que;而默認的que插入是從大到小,所以在結構體中要重載<,如果我們將其<修gai爲>則que的push函數找不到相應的操作符,就會出錯。
另外,如果我們想向優先級隊列中插入指針元素時該怎麼辦?是不是將priority_queue<Node>que;改爲priority_queue<Node*>que;就ok了?
不是!因爲我們不能用結構體中重載的操作符對que中的元素進行比較,結構體中重載的操作符是類Node的操作符,而que中的是指針類型的Node節點,它與結構體中重載的操作符無法匹配。所以我們要另想辦法。
那我們將friend bool operator >(Node node1,Node node2)修改爲friend bool operator >(Node* node1,Node* node2),也就是傳遞的是Node的指針行不行呢
答案是不可以,因爲根據c++primer中重載操作符中講的“程序員只能爲類類型或枚舉類型的操作數定義重載操作符,在吧操作符聲明爲類的成員是,至少有一個類或枚舉類型的參數
按照值或者引用的方式傳遞”,也就是說friend bool operator >(Node* node1,Node* node2)形參中都是指針類型的是不可以的。我們可以如下解決此問題。
//在優先級隊列中存入指針類型的節點
#include<iostream>
#include<queue>
using namespace std;
class Comapre;
class Node
{
private:
friend Comapre;
int key;
char ch;
public:
Node(int num,char c):key(num),ch(c) {}
bool lessthan (const Node* node) const
{
return key<node->key;
}
int GetKey()
{
return key;
}
char GetChar()
{
return ch;
}
};
class Comapre
{
public:
bool operator () (Node*node1,Node*node2)
{
return node1->lessthan(node2);
}
};
int main()
{
Node *n1=new Node(5,'c');
Node *n2=new Node(4,'d');
Node *n3=new Node(6,'e');
priority_queue<Node*,vector<Node*>,Comapre>qu;
qu.push(n1);
qu.push(n2);
qu.push(n3);
int i;
for(i=0; i<3; i++)
{
cout<<qu.top()->GetKey()<<" "<<qu.top()->GetChar()<<endl;
qu.pop();
}
return 0;
}