共同可以使用的模版有
class cmp2 {
public:
bool operator()(const Node& a, const Node& b) {
return a.x < b.x;
}
};
在make_heap和sort里用cmp2(), 在priority_queue里用priority_queue<Node, vector<Node>, cmp2()>
注意传引用之前一定要加const!!!!写成这样就太差了。。。
class cmp2 {
public:
bool operator()(Node a, Node b) {
return a.x < b.x;
}
};
比较有两种重载,一种是类内部的bool operator<( 只有一个参数 ),当然bool operator< 也可以拿到类的外面;另外一种是写一个cmp,利用cmp返回作为sort的第三个参数,就是这样。第一种方法,这里上代码:
#include <iostream>
#include <stdio.h>
#include <queue>
#include <stdlib.h>
#include <functional>
#include <algorithm>
using namespace std;
class Node{
public:
int x, y;
Node( int a= 0, int b= 0 ):x(a),y(b) {}
bool operator<(Node m)const{
return x<m.x;
}
};
/*
重载可以放在外面,不用const修饰
bool operator<( Node a, Node b ){
if( a.x== b.x ) return a.y> b.y;
return a.x> b.x;
}
*/
int main()
{
priority_queue<Node> q;
vector<Node> qq;
for( int i= 0; i< 10; ++i ){
q.push( Node( rand(), rand() ) );
qq.push_back( Node( rand(),rand() ) );
}
sort(qq.begin(),qq.end());
printf("The result of q is :\n");
while( !q.empty() )
{
cout << q.top().x << ' ' << q.top().y << endl;
q.pop();
}
printf("The result of qq is :\n");
for(int i=0;i<qq.size();i++){
printf("%d %d\n",qq[i].x,qq[i].y);
}
return 0;
}
第二种方法:
#include <algorithm>
#include <stdio.h>
using namespace std;
class Node {
public:
int x,y;
Node(int a = 0, int b = 0):x(a),y(b) {}
};
bool cmp(int x, int y) {
return x < y;
}
bool cmp1(const Node a, const Node b) {
return a.x < b.x;
}
class cmp2 {
public:
bool operator()(const Node& a, const Node& b) {
return a.x < b.x;
}
};
int main() {
int a[] = {4,3,1,2,3,5};
sort(a, a + sizeof(a)/sizeof(int), cmp);
for (int i = 0; i < sizeof(a)/sizeof(int); ++i)
printf("%d ",a[i]);
printf("\n-----------------------------------------\n");
Node b[] = {Node(4,4),Node(3,3),Node(1,1),Node(2,2),Node(3,3),Node(5,5)};
//sort(b, b + sizeof(b)/sizeof(Node), cmp1);
sort(b, b + sizeof(b)/sizeof(Node), cmp2());
for (int i = 0; i < sizeof(b)/sizeof(Node); ++i)
printf("%d-%d ",b[i].x, b[i].y);
printf("\n-----------------------------------------\n");
return 0;
}
虽然说bool operator<比较简单,但是bool operator<(ListNode* a, ListNode* b)这样是无法通过的,因此,必须在某些时候定义用于比较的类。其实就是在一个类里放一个bool operator(ListNode* a, ListNode* b)即可,以leetcode中Merge k Sorted lists 为例,转网上某人的一个代码:
#include<iostream>
#include<stdio.h>
#include<stack>
#include<vector>
#include<string>
#include<unordered_set>
#include<unordered_map>
#include<set>
#include<queue>
#include<map>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class cmp
{
public:
bool operator() (ListNode *a,ListNode *b)
{
return a->val > b->val;
}
};
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if(lists.size() == 0)
return NULL;
priority_queue< ListNode * , vector<ListNode *> , cmp > que;//time O(klogn) , space O(k)
for(int i=0;i<=lists.size()-1;i++)
{
if(lists[i]!=NULL)
que.push(lists[i]);//each first Node in the K Lists
}
ListNode *head=NULL,*pre=NULL,*tmp;
while(!que.empty())
{
tmp=que.top();
que.pop();
if(head==NULL)
head=tmp;
else
pre->next=tmp;
pre=tmp;
if(tmp->next!=NULL)
que.push(tmp->next);
}
return head;
}
};
int main(){
Solution s;
//vector<string> res;
// res=s.restoreIpAddresses("172162541");
//bool hello = s.str2num("172162541",3,5);
//int m = 3, n = 6, k = 5, i, j;
//i = ( m) / (m + n) * (k - 1);
ListNode *l11 = new ListNode(1);
ListNode *l12 = new ListNode(4);
ListNode *l13 = new ListNode(7);
l11->next = l12;
l12->next = l13;
ListNode *l21 = new ListNode(2);
ListNode *l22 = new ListNode(5);
ListNode *l23 = new ListNode(8);
l21->next = l22;
l22->next = l23;
ListNode *l31 = new ListNode(3);
ListNode *l32 = new ListNode(6);
ListNode *l33 = new ListNode(9);
l31->next = l32;
l32->next = l33;
vector<ListNode*> lists;
lists.push_back(l11);
lists.push_back(l21);
lists.push_back(l31);
ListNode* res = s.mergeKLists(lists);
while (res != NULL) {
cout<<res->val<<" ";
res = res->next;
}
return 0;
}
另外,使用priority_queue时建堆的复杂度为O(nlogn), 今天还发现STL里有一个建堆复杂度为O(n)的模版,建堆的复杂度本来就应该是O(n),把刚才那题用这种方式再敲一遍:
需要注意的地方在于pop_heap()这个函数,当pop之后,函数并没有把极值元素删除,而是放在vector末位。
而push_heap()这个函数,它假设vector最后一个是新添加进来的,之前已经是堆了,再做调整。
pop_heap();
它的函数原型是:void pop_heap(first_pointer,end_pointer,compare_function);
作用:pop_heap()不是真的把最大(最小)的元素从堆中弹出来。而是重新排序堆。它
把first和last交换,然后将[first,last-1)的数据再做成一个堆。
接着是push_heap() void pushheap(first_pointer,end_pointer,compare_function);
作用:push_heap()假设由[first,last-1)是一个有效的堆,然后,再把堆中的新元素加
进来,做成一个堆。
可以单步以下代码观察这个现象:
// range heap example
#include <iostream> // std::cout
#include <algorithm> // std::make_heap, std::pop_heap, std::push_heap, std::sort_heap
#include <vector> // std::vector
int main () {
int myints[] = {10,20,30,5,15};
std::vector<int> v(myints,myints+5);
std::make_heap (v.begin(),v.end());
std::cout << "initial max heap : " << v.front() << '\n';
std::pop_heap (v.begin(),v.end());
v.pop_back();
std::cout << "max heap after pop : " << v.front() << '\n';
v.push_back(99);
std::push_heap (v.begin(),v.end());
std::cout << "max heap after push: " << v.front() << '\n';
std::sort_heap (v.begin(),v.end());
std::cout << "final sorted range :";
for (unsigned i=0; i<v.size(); i++)
std::cout << ' ' << v[i];
std::cout << '\n';
return 0;
}
其实priority_queue就是这么个东西:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class priority_queue
{
private:
vector<int> data;
public:
void push( int t ){
data.push_back(t);
push_heap( data.begin(), data.end());
}
void pop(){
pop_heap( data.begin(), data.end() );
data.pop_back();
}
int top() { return data.front(); }
int size() { return data.size(); }
bool empty() { return data.empty(); }
};
int main()
{
priority_queue test;
test.push( 3 );
test.push( 5 );
test.push( 2 );
test.push( 4 );
while( !test.empty() ){
cout << test.top() << endl;
test.pop(); }
return 0;
}
好,这个题总算是完整地过了:
注意使用cmp()或者cmp1都可以:
class cmp {
public:
bool operator()(ListNode* a, ListNode* b) {
return a->val > b->val;
}
};
bool cmp1 (ListNode* a, ListNode* b) {
return a->val > b->val;
}
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class cmp {
public:
bool operator()(ListNode* a, ListNode* b) {
return a->val > b->val;
}
};
bool cmp1 (ListNode* a, ListNode* b) {
return a->val > b->val;
}
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
// Note: The Solution object is instantiated only once and is reused by each test case.
ListNode *head = NULL, *cur = NULL;
vector<ListNode*>::iterator it = lists.begin();
while (it != lists.end()) {
if (*it == NULL)
lists.erase(it);
else
it++;
}
if (lists.size() < 1)
return NULL;
make_heap(lists.begin(), lists.end(), cmp());
while (lists.size() > 0) {
if (head == NULL)
head = cur = lists[0];
else {
cur->next = lists[0];
cur = cur->next;
}
pop_heap(lists.begin(), lists.end(), cmp());
if (lists[lists.size() - 1]->next != NULL) {
lists[lists.size() - 1] = lists[lists.size() - 1]->next;
push_heap(lists.begin(), lists.end(), cmp());
}
else
lists.pop_back();
}
return head;
}
};
import java.util.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class Test {
public String name;
public int ID;
Test(String name, int ID){
this.name = name;
this.ID = ID;
}
public static void main(String args[]) {
Comparator<Test> cmp = new Comparator<Test>() {
@Override
public int compare(Test o1, Test o2) {
// Different from cpp, 1, 0, -1 are all needed to be defined
return o1.ID>=o2.ID?1:-1;
}
};
Queue<Test> priorityQueue = new PriorityQueue<Test>(1, cmp);
priorityQueue.add(new Test("t2",2));
priorityQueue.add(new Test("t3",3));
priorityQueue.add(new Test("t1",1));
priorityQueue.add(new Test("t4",4));
System.out.print("name:"+priorityQueue.peek().name);
}
}