优先级队列要求,当容器的元素类型是类或者结构体时,“<”运算符必须有定义,优先级队列默认情况下就是按“<”运算符来决定元素大小的。
例子如下:
#include<stdio.h>
#include<functional>
#include<queue>
#include<vector>
using namespace std;
//定义结构,使用运算符重载,自定义优先级1
struct cmp1 {
bool operator ()(int &a, int &b) {
return a>b;//最小值优先
}
};
struct cmp2 {
bool operator ()(int &a, int &b) {
return a<b;//最大值优先
}
};
int a[] = { 14,10,56,7,83,22,36,91,3,47,72,0 };
int main()
{
priority_queue<int>que;//采用默认优先级构造队列
priority_queue<int, vector<int>, cmp1>que1;//最小值优先
priority_queue<int, vector<int>, cmp2>que2;//最大值优先
priority_queue<int, vector<int>, greater<int> >que3;//注意“>>”会被认为错误,
//这是右移运算符,所以这里用空格号隔开
priority_queue<int, vector<int>, less<int> >que4;////最大值优先
int i;
for (i = 0; a[i]; i++) {
que.push(a[i]);
que1.push(a[i]);
que2.push(a[i]);
que3.push(a[i]);
que4.push(a[i]);
}
printf("采用默认优先关系:\n(priority_queue<int>que;)\n");
printf("Queue 0:\n");
while (!que.empty()) {
printf("%3d", que.top());
que.pop();
}
puts("");
puts("");
printf("采用结构体自定义优先级方式一:\n(priority_queue<int,vector<int>,cmp>que;)\n");
printf("Queue 1:\n");
while (!que1.empty()) {
printf("%3d", que1.top());
que1.pop();
}
puts("");
printf("Queue 2:\n");
while (!que2.empty()) {
printf("%3d", que2.top());
que2.pop();
}
puts("");
puts("");
printf("采用头文件\"functional\"内定义优先级:\n(priority_queue<int,vector<int>,greater<int>/less<int> >que;)\n");
printf("Queue 3:\n");
while (!que3.empty()) {
printf("%3d", que3.top());
que3.pop();
}
puts("");
printf("Queue 4:\n");
while (!que4.empty()) {
printf("%3d", que4.top());
que4.pop();
}
system("pause");
return 0;
}
还有一种方法:
#include<iostream>
#include<queue>
using namespace std;
class node {
public:
int x, y;
node(int x, int y) :x(x), y(y) {}
friend bool operator <(const node&a, const node&b) {
if (a.y == b.y)
return a.x > b.x;
else
return a.y>b.y;
}
};
//class node {
//public:
// int x, y;
// node(int x, int y) :x(x), y(y) {}
// bool operator <(const node&a) const{
// if (y == a.y)
// return x > a.x;
// else
// return y>a.y;
// }
//};
int main() {
priority_queue<node> q;//优先级队列要求,当容器的元素类型是类或者结构体时,“<”运算符必须有定义,优先级队列默认情况下就是按“<”运算符来决定元素大小的
q.push(node(1, 5));
q.push(node(3, 1));
q.push(node(1, 1));
q.push(node(3, 2));
while (!q.empty()) {
cout << q.top().x << " " << q.top().y << " " << endl;
q.pop();
}
system("pause");
return 0;
}
接下来看题:
法1:优先级队列
class Solution {
public:
struct cmp { //自定义比较函数,对新的数据类型的<进行重载
bool operator()(ListNode *a, ListNode *b) {
return a->val > b->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<ListNode*, vector<ListNode*>, cmp> pri_queue;
for (auto p : lists)
{
if (p != NULL)
pri_queue.push(p);//压入所有链表的头结点
}
ListNode *pHead = new ListNode(-1);
ListNode *pCur = pHead;
while (!pri_queue.empty())
{
ListNode *top = pri_queue.top(); pri_queue.pop();
pCur->next = top;
pCur = pCur->next;
if (top->next != NULL)
{
pri_queue.push(top->next);
}
}
pCur = pHead->next;
delete pHead;
pHead = NULL;
return pCur;
}
};
法2:归并(思路与合并两个排序链表相同)
相当漂亮的解法!!!
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.size() == 0)return NULL;
return merge(lists, 0, lists.size() - 1);
}
ListNode*merge(vector<ListNode*>& lists, int left, int right)//归并
{
if (left == right) return lists[left];
int mid = left + (right - left) / 2;
ListNode *l1 = merge(lists, left, mid);//[left, mid]的链表合并完成,返回合并后的头结点
ListNode *l2 = merge(lists, mid + 1, right);//[mid + 1, right]的链表合并完成,返回合并后的头结点
return mergeTwoLists(l1, l2);
}
ListNode* mergeTwoLists(ListNode*p1, ListNode*p2)
{
ListNode*t1, *t2;//双指针
t1 = p1, t2 = p2;
ListNode*newHead = new ListNode(-1);
ListNode*t = newHead;
while (t1 != NULL && t2 != NULL)
{
if (t1 != NULL&&t2 != NULL)
{
if (t1->val <= t2->val)
{
t->next = t1;
t1 = t1->next;
t = t->next;
}
else
{
t->next = t2;
t2 = t2->next;
t = t->next;
}
}
}
if (t1 == NULL)
{
t->next = t2;
}
else
t->next = t1;
return newHead->next;
}
};