作为队列的一种,优先级队列首先要有出队、入队、取队首、判空等基本操作,所不同的是出队、入队会改变堆中元素的顺序。
0. 调整堆的顺序(最大堆)
template<class T>void heapify(T *array, const int length, int i) {
if (i < length) {
int parent_idx = i;
int parent_val = array[parent_idx];
int child =2 * i + 1;
while (child < length) {
if (child + 1 < length && array[child] < array[child+1])
child ++;
if (parent_val < array[child]) {
array[parent_idx] = array[child];
parent_idx = child;
child = 2 * p +1;
} else
break;
}
array[parent_idx] = parent_val;
//此时子树已经迭代完成,孩子中没有更大的了,不会上移,parent_val也不会下移了
}
};
1.入队
入队前,队列已经是一个堆了,所以入队的时候,只需要将它与parent比较,使它和parent的关系满足堆的性质。
template<class T>
void PriorityQueue<T>::enQueue(T *ele) {
if (heap_size + 1> max_size) { //堆已满,需重新分配
T *old_heap = heap;
heap = new T[max_size * 2];
for (int i = 0; i < heap_size; i++)
heap[i] = old_heap[i];
delete old_heap;
old_heap = NULL;
}
heap[heap_size] = *ele;
int curr_idx = heap_size;
int par_idx = parent(heap_size);
++ heap_size;
while (par_idx >= 0 && heap[curr_idx] > heap[par_idx]) {
T tmp = heap[curr_idx];
heap[par_idx] = tmp;
curr_idx = par_idx;
par_idx = parent(curr_idx);
}
}
2. 出队
template<class T>
void PriorityQueue<T>::deQueue(T * ele) {
heap[0] = heap[heap_size - 1];
-- heap_size;
heapify(heap, heap_size, 0);
}
3. STL中的优先级队列适配器
#include <iostream>
#include <queue>
using namespace std;
template <class T>
class Element {
public:
Element(int p, T a) {priority = p; data = a;}
inline friend bool operator < (const Element<T> &a, const Element<T> &b) {
return a.priority < b.priority? true: false;
}
void PrintData() {
cout << data << "(pri: " << priority << ")";
}
private:
int priority;
T data;
};
int main()
{
cout << "Hello World" << endl;
priority_queue<Element<int> > pque;
pque.push(Element<int>(1, 20));
pque.push(Element<int>(3, 30));
pque.push(Element<int>(2, 40));
pque.push(Element<int>(3, 50));
pque.push(Element<int>(3, 10));
int size = (int)pque.size();
cout << "size: " << size << endl;
for (int i = 0; i < size; i++) {
pque.top().PrintData();
pque.pop();
}
cout << endl << "size: " << pque.size() << endl;
return 0;
}