优先队列的应用 C++实现
优先队列的应用 C++实现
优先队列可以用堆来实现, 堆底层可以用数组表示,
通过索引关系,可以表示成一颗二叉完全树
C++的STL提供了相应的容器适配器
包含在queue
头文件中
下面通过一道题来看如何使用它
给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
string frequencySort(string s) {
}
首先,统计字符出现的频率,通过map容器可以很简单的统计出来
map<char, int> mp;
for (auto e : s)
{
++mp[e];
}
然后我们需要构建一个优先队列,而且要指定优先队列的排序方式
因此我们定义了一个自己的结构体, 并定义了<
操作符(降序定义小于号,升序大于号),
struct Node
{
Node(const pair<char, int> &val) : p(val) {}
pair<char, int> p;
};
bool operator<(const Node &a, const Node &b)
{
return a.p.second < b.p.second;
}
然后把键值对放入优先队列中
for (auto e : mp)
{
pq.push(make_pair(e.first, e.second));
}
要用的时候,依次取出来就是了,每次取出的都是里面最大(或最小)的
string res;
while (!pq.empty())
{
for (int i = 0; i < pq.top().p.second; ++i)
res.push_back(pq.top().p.first);
pq.pop();
}
还有好几个类似的题,都可以用这种方式解决
比如 :
下面是堆的实现, 还是建议掌握的
#include <vector>
using namespace std;
template <class T>
class Heap
{
public:
Heap(size_t maxElems)
{
h = new HeapStruct;
h->Elems = new T[maxElems + 1];
h->Capacity = maxElems;
h->size = 0;
}
~Heap()
{
destroy();
}
void insert(T x)
{
size_t i;
if (isFull())
{
return;
}
for (i = ++h->size; i / 2 > 0 && h->Elems[i / 2] > x; i /= 2)
{
h->Elems[i] = h->Elems[i / 2];
}
h->Elems[i] = x;
}
T deleteMin()
{
size_t i, child;
T minElems, lastElems;
if (isEmpty())
return h->Elems[0];
minElems = h->Elems[1];
lastElems = h->Elems[h->size--];
for (i = 1; i * 2 <= h->size; i = child)
{
child = i * 2;
if (child != h->size && h->Elems[child + 1] < h->Elems[child])
++child;
if (lastElems > h->Elems[child])
h->Elems[i] = h->Elems[child];
else
break;
}
h->Elems[i] = lastElems;
return minElems;
}
bool isFull()
{
return h->size == h->Capacity;
}
bool isEmpty()
{
return h->size == 0;
}
T findMin()
{
return h->Elems[1];
}
private:
void destroy()
{
delete h->Elems;
delete h;
}
void makeEmpty() {}
struct HeapStruct
{
size_t Capacity;
size_t size;
T *Elems;
};
HeapStruct* h;
};