优先队列
模板
模板:priority_queue<Type, Container, Functional>
Type:进入队列的数据类型
Container:保存数据的容器(一般vector,deque,不能使用list)
Functional:元素比较方式
默认比较方式
一般默认priority_queue(默认大顶堆):
以int为例:priority_queue : 大顶堆实现,等价于priority_queue<int,vector,less>,出队列时元素会按照从大到小顺序排列。
less 被替换成 greater,出队列时元素按照从小到大顺序排列。
自定义比较方式
自定义的实现方式有好几种,一般本人比较习惯的是定义一个仿函数cmp。
struct cmp{
// 注意:返回true : b优先级高于a,出队列时b先出,a后出。
// 返回false : a优先级高,出队列时a先出。
bool operator() (T a,T b){
return a > b;
}
};
priority_queue<T,vector<T>,cmp> pq;
...
复杂度分析
时间复杂度: O(nlogn)
堆的初始化,时间复杂度为O(n)。
在堆排序中一次进行堆的初始化操作,其时间复杂度为O(n),n-1次进行堆的调整,每次调整的时间复杂度为O(logn),所以,堆排序的时间复杂度为O(nlogn)。
因为堆的每次插入、删除元素均需要重新调整堆,所以插入与删除元素的时间复杂度为O(logn)。
空间复杂度:O(1)
堆排序是就地排序,空间复杂度O(1)。
案例分析
合并 K 个排序链表
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
struct cmp{
bool operator() (ListNode* a,ListNode* b){
return a->val > b->val;
}
};
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
priority_queue<ListNode*,vector<ListNode*>,cmp> pq;
for (auto Node : lists) if (Node) pq.push(Node);
ListNode *dummy = new ListNode(0);
ListNode *p = dummy;
while (!pq.empty()){
auto cur = pq.top();
pq.pop();
p->next = cur;
p = p->next;
if (cur->next) pq.push(cur->next);
}
p->next = nullptr;
p = dummy->next;
delete dummy;
return p;
}
};