Ps:本文是写了C++排序算法(一)之堆排序之后
(个人觉得这个C++ STL 中的优先队列很有用,所以放于0x0节:
不过为了加深对它的理解,在0x1~0x3节会对它进行一个模拟。
如果只想要会用,看完0x0节即可!)
==================================================
0x0 C++ STL中的priority_queue
priority_queue<Type, Container, Functional>
Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式
【STD 手册】:
namespace std {template < class T ,class Container = vector<T> ,class Compare = less <typename Container::value_type> >class priority_queue ;}
【可以看到】:
容器默认是vector,比较方式默认是less,默认比较是operator< ,产生的结果默认是大根堆(最大堆)
【使用方法】:
priority_queue<int> pq1; //大根堆priority_queue<int, vector<int>, greater<int> > pq2; //知道如何产生小根堆(最小堆)了吧?priority_queue<Node> pq3 ; //自定义结点,大根堆, 此时要重载operator<priority_queue<Node, vector<Node>, cmp > pq4; //自定义结点,小根堆, cmp是自己写的比较函数,因为greater<Node>没定义,重载opreator>没用
【核心函数】:
push() 将一个元素置于priority queue中top() 返回priority queue中的下一个元素pop() 从priority queue 中移除一个元素
【代码范例】:
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
struct Node{
int x,y;
Node(int a=0,int b=0):x(a),y(b){}
};
bool operator<(Node a,Node b){
if(a.x == b.x) return a.y > b.y;
return a.x > b.x;
}
struct cmp{
bool operator()(Node a,Node b){
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
};
int main()
{
//-----pq1------
cout<<"pq1(大根堆):"<<endl;
priority_queue<int> pq1;
for(int i=0; i<10; i++)
{
pq1.push(rand());
}
while(!pq1.empty())
{
cout<<pq1.top()<<" ";
pq1.pop();
}
cout<<endl;
//-----pq2------
cout<<"pq2(小根堆):"<<endl;
priority_queue<int,vector<int>,greater<int> > pq2;
for(int i=0; i<10; i++)
{
pq2.push(rand());
}
while(!pq2.empty())
{
cout<<pq2.top()<<" ";
pq2.pop();
}
cout<<endl;
//-----pq3------
//这里就要重载这个operator<
cout<<"pq3(大根堆):"<<endl;
priority_queue<Node> pq3;
for(int i=0; i<10; i++)
{
pq3.push(Node(rand(),rand()));
}
while(!pq3.empty())
{
cout<<"("<<pq3.top().x<<","<<pq3.top().y<<") ";
pq3.pop();
}
cout<<endl;
//-----pq4------
//这里重载operator>没用
//因为greate<Node>里面也没有重载
//最好的方法就是自己写个struct cmp
cout<<"pq4(小根堆):"<<endl;
priority_queue<Node,vector<Node>,cmp > pq4;
for(int i=0; i<10; i++)
{
pq4.push(Node(rand(),rand()));
}
while(!pq4.empty())
{
cout<<"("<<pq4.top().x<<","<<pq4.top().y<<") ";
pq4.pop();
}
cout<<endl;
return 0;
}
0x1 什么是最大优先级队列
它不是一种普通的先进先出队列(队列是什么?天啊!),它维护的元素有个优先级属性,不管如何进队列,出列队的都是 优先级最大的元素!
0x2 应用在哪里
计算机的分时调度啊最小生成树的Prim算法...
0x3 操作有?
INSERT(S,x) :将元素 x 插入到集合 S
MAXIMUM(S): 返回 S 中具有最大关键字的元素
EXTRACT-MAX(S): 去掉并返回 S 中的具有最大关键字的元素
INCREASE-KEY(S,x , k) :将元素 x 的关键字的值增到 k ,这里 k 值不能小于 x 的原关键字的值
0x4 代码实现
【测试代码】
#include "Priority_Queue.h"
#include <iostream>
using namespace std;
int main()
{
//test for Insert()
Priority_Queue pq;
for(int i = 0;i < 5;i++)
pq.insert(rand()%10);
//test for maxNum()
for(int i = 0;i < 5;i++)
cout<<pq.m_pq[i]<<" ";
cout<<endl<<pq.maxNum()<<endl;
//test for increase_key()
pq.increase_key(2,pq.m_pq[2]+15);
for(int i = 0;i < 5;i++)
cout<<pq.m_pq[i]<<" ";
cout<<endl<<pq.maxNum()<<endl;
//test for extract_max()
while(!pq.empty())
{
cout<<pq.extract_max()<<" ";
}
cout<<endl;
return 0;
}
【Priority_Queue代码】
#ifndef PRIORITY_QUEUE_H
#define PRIORITY_QUEUE_H
#include <vector>
#include <iostream>
using namespace std;
class Priority_Queue
{
public:
Priority_Queue();
virtual ~Priority_Queue();
//类似 pq.top()
int maxNum()
{
return m_pq.front();
}
//类似 pq.push()
void insert(const int data)
{
m_pq.push_back(data);
make_heap();
}
//类似 pq.top() + pq.pop()
//去掉并返回pq的最大元素
int extract_max()
{
int max = m_pq.front();
swap(m_pq[0],m_pq[m_pq.size()-1]);
m_pq.pop_back();
MaxHeapify(0);
return max;
}
bool empty()
{
if(m_pq.size() == 0)
return true;
else
return false;
}
void increase_key(int i,int key)
{
if(m_pq[i] > key)
{
cout<<"new key is smallor than current key!"<<endl;
return;
}
m_pq[i] = key;
//此时可能会破坏堆性质,需要调整
//不断和父亲交换如果比父亲大的话 m_pq[(i-1)/2] 就是父亲
while( i >= 1 && m_pq[(i-1)/2] < m_pq[i])
{
swap(m_pq[(i-1)/2],m_pq[i]);
i = (i-1)/2;
}
}
void make_heap()
{
for(int i = m_pq.size()/2;i >= 0; i--)
{
MaxHeapify(i);
}
}
void MaxHeapify(unsigned int i)
{
unsigned int left = (i<<1)+1;
unsigned int right = (i<<1)+2;
unsigned int max = i;
if(left < m_pq.size() && m_pq[i] < m_pq[left])
max = left;
if(right < m_pq.size() && m_pq[max] < m_pq[right])
max = right;
if(max != i)
{
swap(m_pq[i],m_pq[max]);
MaxHeapify(max);
}
}
protected:
public:
vector<int> m_pq;
};
#endif // PRIORITY_QUEUE_H