实现的一个按int类型值从大到小的优先队列,使用大根堆实现。
#include <iostream>
#include <vector>
using namespace std;
class priority_queue
{
private:
vector<int> data;// data[0] is not used
void sift_up(int index)
{
int parent_index = index / 2;
if (parent_index == 0)
{
return;
}
else
{
if (data[index] > data[parent_index])
{
int temp = data[index];
data[index] = data[parent_index];
data[parent_index] = temp;
sift_up(parent_index);
}
}
}
void sift_down(int index)
{
int left_son_index = index * 2;
if (left_son_index >= (int)data.size())
{
return;
}
else
{
// which son to swap with
int swap_index = left_son_index;
if (left_son_index + 1 < (int)data.size() && data[left_son_index] < data[left_son_index] + 1)
{
swap_index = left_son_index + 1;
}
// swap!
if (data[index] < data[swap_index])
{
int temp = data[index];
data[index] = data[swap_index];
data[swap_index] = temp;
sift_down(swap_index);
}
}
}
void insert(int value)
{
data.push_back(value);
sift_up(data.size() - 1);
}
public:
priority_queue()
{
data.push_back(0);// data[0] is not used
}
void push(int value)
{
insert(value);
}
void pop()
{
if (data.size() > 1)
{
data[1] = data[data.size() - 1];
data.erase(data.end() - 1);
sift_down(1);
}
}
int top()
{
if (data.size() > 1)
{
return data[1];
}
else
{
// raise error!
return 0;
}
}
};
void test_priority_queue()
{
priority_queue pqueue;
pqueue.push(2);
pqueue.push(3);
pqueue.push(1);
for (int i = 0; i < 3; ++i)
{
cout << pqueue.top() << endl;
pqueue.pop();
}
}
int main()
{
test_priority_queue();
return 0;
}
在上面的程序的基础上,我们再添加C++的一些语法机制,可以实现一个功能上和STL中priority_queue一模一样的类。
下面是代码:
#include <iostream>
#include <vector>
using namespace std;
// 下面实现了一个优先级队列。
// 它的用法和STL中的priority_queue是一样的。
template <typename ELEMENT_TYPE, typename STORAGE_CONTAINER, typename COMPARE_CLASS>
class priority_queue
{
private:
STORAGE_CONTAINER data;// data[0] is not used
void sift_up(int index)
{
COMPARE_CLASS comp;
int parent_index = index / 2;
if (parent_index == 0)
{
return;
}
else
{
if (comp(data[index], data[parent_index]))
{
ELEMENT_TYPE temp = data[index];
data[index] = data[parent_index];
data[parent_index] = temp;
sift_up(parent_index);
}
}
}
void sift_down(int index)
{
COMPARE_CLASS comp;
int left_son_index = index * 2;
if (left_son_index >= (int)data.size())
{
return;
}
else
{
// which son to swap with
int swap_index = left_son_index;
if (left_son_index + 1 < (int)data.size() && !comp(data[left_son_index], data[left_son_index + 1]))
{
swap_index = left_son_index + 1;
}
// swap!
if (!comp(data[index], data[swap_index]))
{
ELEMENT_TYPE temp = data[index];
data[index] = data[swap_index];
data[swap_index] = temp;
sift_down(swap_index);
}
}
}
void insert(ELEMENT_TYPE &value)
{
data.push_back(value);
sift_up(data.size() - 1);
}
public:
priority_queue()
{
data.push_back(0);// data[0] is not used
}
void push(ELEMENT_TYPE &value)
{
insert(value);
}
void pop()
{
if (data.size() > 1)
{
data[1] = data[data.size() - 1];
data.erase(data.end() - 1);
sift_down(1);
}
}
ELEMENT_TYPE top()
{
if (data.size() > 1)
{
return data[1];
}
else
{
// raise error!
return 0;
}
}
bool empty()
{
return data.size() == 1;
}
size_t size()
{
return data.size() - 1;
}
};
// 实现一个“人物类”,将此类作为元素添加到优先级队列中做测试。
// 人的年龄与优先级成正比。
struct person
{
int age;
person()
{
age = 0;
}
person(int init_age)
{
age = init_age;
}
};
struct compare_person
{
bool operator()(const person& left, const person& right) const
{
return left.age > right.age;
}
};
ostream &operator<<(ostream &os, person &p)
{
cout << "I'm " << p.age << " years old.";
return os;
}
// 测试函数:测试实现的优先级队列是否可以正常工作。
void test_priority_queue()
{
priority_queue<person, vector<person>, compare_person> pqueue;
pqueue.push(person(11));
pqueue.push(person(13));
pqueue.push(person(12));
cout << pqueue.size() << endl;
while (!pqueue.empty())
{
cout << pqueue.top() << endl;
pqueue.pop();
}
}
int main()
{
test_priority_queue();
return 0;
}