#ifndef TG_SMALL_QUEUE_H
#define TG_SMALL_QUEUE_H
#include<vector>
#include<memory>
template<typename PriorityType, typename ValueType>
/// 最小优先队列
class tg_small_queue
{
struct node
{
ValueType data;
PriorityType level;
node(PriorityType& level, ValueType& data):data(data),level(level)
{
}
};
private:
std::vector<std::shared_ptr<node>> _arr;
public:
tg_small_queue()
{
_arr.reserve(1024);
}
void enqueue(PriorityType& level, ValueType& data)
{
_arr.emplace_back(std::make_shared<node>(level, data));
up_adjust(_arr);
}
bool dequeue(ValueType& out_data)
{
if (_arr.size() == 0)
{
return false;
}
//出队列操作,弹出数据头元素
out_data = _arr[0]->data;
//用尾元素填充头元素
_arr[0] = _arr[_arr.size() - 1];
//删除尾节点
_arr.pop_back();
down_adjust(_arr);
return true;
}
int size()
{
return _arr.size();
}
private:
static void up_adjust(std::vector<std::shared_ptr<node>>& arr)
{
if (arr.size() < 2)
{
return;
}
int parent = arr.size() / 2 - 1;
while (parent >= 0)
{
int left = 2 * parent + 1;
if (left+1 < arr.size() && arr[left]->level > arr[left+1]->level)
{
left++;
}
//如果parent节点大于它的某个子节点,交换
if (arr[parent]->level > arr[left]->level)
{
auto temp = arr[parent];
arr[parent] = arr[left];
arr[left] = temp;
parent = (parent + 1) / 2 - 1;
}
else
{
break;
}
}
}
static void down_adjust(std::vector<std::shared_ptr<node>>& arr)
{
if (arr.size() < 2)
{
return;
}
int parent = 0;
auto node = arr[parent];
auto left = 2 * parent + 1;
while (left < arr.size())
{
//选择小的
if (left + 1 < arr.size() && arr[left]->level > arr[left+1]->level)
{
left++;
}
if (node->level > arr[left]->level)
{
arr[parent] = arr[left];
parent = left;
left = 2 * parent + 1;
}
else
{
break;
}
}
arr[parent] = node;
}
};
#endif // TG_SMALL_QUEUE_H
测试代码
#include <iostream>
#include <memory.h>
#include <string.h>
#include<random>
#include "tg_small_queue.h"
void test()
{
tg_small_queue<uint, uint> que;
std::random_device rd;
for(int i=0; i<20; i++)
{
uint d = rd()%100;
que.enqueue(d, d);
}
uint d;
while (que.dequeue(d))
{
std::cout<<d<<std::endl;
}
}
int main()
{
test();
return 0;
}