STL里面的优先队列没有查找功能,但是在写A*算法时必须要对优先队列进行数据查找,那么就只能自己实现了。相比于STL库里的优先队列,增加了查找功能。
参考文章:http://blog.csdn.net/morewindows/article/details/6709644
#ifndef PRIORITY_QUEUE_X_H
#define PRIORITY_QUEUE_X_H
#include <vector>
using namespace std;
/*
* 1, 创建最小堆,二叉堆是完全二叉树。数据的存储结构可以用数组
2, 堆得数据插入操作:每次插入都是将新数据放在数组最后,通过调用函数HeapAdjustUp实现
3, 堆的数据删除操作:每次只能删除第0个数据,把最后一个数据值赋给根节点,然后从根节点开始一次自上而下的调整,借助函数HeapAdjustDown。
4, 对于节点i,它的左孩子是 2*i+1,右孩子是 2*i+2。第一个节点在数组的下标0处
*/
template<class T>
class Priority_Queue
{
public:
Priority_Queue(int size=20):t_size(0)
{
var.resize(size);
}
T& top();
void pop();
void pop(T & tar);
void push(T & dat);
bool find(T & dst);
bool empty() const;
void make_queue_sorted(vector<T>&dst);
private:
void BuildHeap();
void HeapAdjustUp(int i);
void HeapAdjustDown(int i);
private:
unsigned int t_size;
vector<T> var;
};
template<class T>
void _swap(T &a, T& b)
{
T temp;
temp = a;
a = b;
b = temp;
}
template<class T>
T& Priority_Queue<T>::top()
{
Node tmp(INT_MAX, INT_MAX);
if(!empty())
return var[0];
else
{
return tmp;
}
}
template<class T>
bool Priority_Queue<T>::empty() const
{
return t_size == 0;
}
template<class T>
bool Priority_Queue<T>::find(T & dst)
{
unsigned int i;
for(i=0; i<t_size; i++)
{
if(dst == var[i])
return 1;
}
return 0;
}
template<class T>
void Priority_Queue<T>::HeapAdjustDown(int i)
{
unsigned int j;
T temp = var[i];
j = 2*i+1; //左孩子
while(j<t_size)
{
if(j+1 < t_size && var[j+1] < var[j]) //在左右孩子中找最小的
j++;
if(var[j] >= temp)
break;
var[i] = var[j];
i = j;
j = 2*i + 1;
}
var[i] = temp;
}
template<class T>
void Priority_Queue<T>::pop()
{
if(t_size>0)
{
_swap(var[0], var[t_size-1]);
t_size--;
HeapAdjustDown(0);
}
}
template<class T>
void Priority_Queue<T>::pop(T & tar)
{
unsigned int i;
for(i=0; i<t_size; i++)
{
if(tar == var[i])
{
_swap(var[i], var[t_size-1]);
t_size--;
HeapAdjustDown(i);
break;
}
}
}
template<class T>
void Priority_Queue<T>::HeapAdjustUp(int i)
{//对于一个二叉堆,父节点肯定大于它的子节点,所以在插入时只需关注和父节点的关系
int j=(i-1)/2;//父节点下标
T temp = var[i];
while((i-1)>=0 && var[j]>temp)//类似于插入排序,使用(i-1)判断是因为 当i=0时(i-1)/2恒为0
{
var[i] = var[j]; //父节点大于子节点,,父节点下移
i=j;
j=(i-1)/2;
}
var[i] = temp;
}
template<class T>
void Priority_Queue<T>::push(T & dat)
{
if(t_size+1 > var.size())
var.resize(2*t_size + 1);
var[t_size] = dat;
t_size++;
HeapAdjustUp(t_size-1);
}
template<class T>
void Priority_Queue<T>::make_queue_sorted(vector<T>&dst)
{
unsigned int size, i;
//临时保存数据
size = t_size;
vector<T> tmpvec;
tmpvec.resize(var.size());
memcpy(tmpvec.data(), var.data(), var.size()*sizeof(T));
//排序
for(i=0; i<size; i++)
{
_swap(var[0], var[size-1-i]);
t_size--;
HeapAdjustDown(0);
}
//对参数赋值
dst.resize(size);
memcpy(dst.data(), var.data(), size*sizeof(T));
//复原数组
t_size = size;
memcpy(var.data(), tmpvec.data(), var.size()*sizeof(T));
}
#endif