優先級隊列幾個應用詳解(friend bool operator)

原文鏈接:http://blog.csdn.net/liuzhanchen1987/article/details/7856893

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;
}

 

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