此文章用到了之前堆的建立的代码,下面是链接 堆的建立
1.优先级队列
优先级队列 是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。
#pragma once
#include <cassert>
#include <iostream>
#include <cstdlib>
#include "Heap.h"
using namespace std;
template <class T , class Compare = Greater<T>>
class PriorityQueue
{
public:
PriorityQueue(T* array, size_t size)
:_h(array, size)
{}
void Push(const T& d)
{
_h.Push(d);
}
void Pop()
{
_h.Pop();
}
const T& Top()
{
return _h.GetTop();
}
protected:
Heap <T, Compare> _h;
};
void TestPriorityQueue()
{
int a[] = { 3, 8, 12, 2, 19, 11, 14, 13, 15, 10 };
PriorityQueue<int> a1(a, 10);
}
2.n个数中找出最大的前k个数
在有大量的数据时,找出最大的前k个数。此类问题可以用堆来解决。
首先,取出n个数据中的前k个数,创建一个有k个数据的小堆。
然后,把后面的数据依次和堆顶的数据比较,找出俩个数中大的数据放在堆顶,调用向下调整算法,保证这是一个小堆。这样就可以找出最大的前k个数。
找出最小的k个数的方法也类似。
注意:找最大数时建的是小堆,找最小数时建的是大堆。
#pragma once
#include <cassert>
#include <iostream>
#include <cstdlib>
using namespace std;
#define K 10
#define N 10000
template <class T>
//将根节点向下调整
void AdjustDown(T *top,int root)
{
assert(root < K);
size_t parent = root;
size_t child = parent * 2 + 1;
while (child < K)
{
if (child + 1 < K && top[child + 1] < top[child])
{
++child;
}
if (top[child] < top[parent] && child < K)
{
swap(top[parent], top[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
return;
}
}
}
template <class T>
void GetTopK(T *arr,T *top)
{
assert(K < N);
for (size_t i = 0; i < K; i++)//取出N个数据的前K个数
{
top[i] = arr[i];
}
for (int j = (K - 2) / 2; j >= 0; j--)//创建一个有K个数据的小堆
{
AdjustDown(top, j);
}
for (size_t i = K; i < N; i++)//比较第K+1--第N个数据,找出最大的K个数
{
if (arr[i] > top[0])
{
swap(arr[i], top[0]);
AdjustDown(top, 0);
}
}
}
template <class T>
void print(T *top)
{
for (size_t i = 0; i < K; i++)
{
cout << top[i] << " ";
}
cout << endl;
}
void TestGetTopK()
{
int arr[N] = { 0 };
int top[K] = { 0 };
for (size_t i = 0; i < N; i++)
{
arr[i] = i;
}
GetTopK(arr, top);
print(top);
}
3.堆排序
以升序为例,堆排序首先建一个小堆,找到最小的数据,放到最后。通过向下调整算法(此时不用管数组的最后一个元素),找到最小的数据,放到最后,这样依次操作,可把数组排序。
如图,一个数组a
建成小堆为
交换堆顶与最后的数据
数组调整为
最小的数调整到后
代码:
#pragma once
#include <cassert>
#include <iostream>
#include <cstdlib>
using namespace std;
template <class T>
void Adjustdown(T* arr ,size_t root,size_t size)
{
size_t parent = root;
size_t child = parent * 2 + 1;
while (parent < size)
{
if (arr[child] > arr[child + 1] && child + 1 < size)
{
++child;
}
if (arr[child] < arr[parent] && child < size)
{
swap(arr[child], arr[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
template <class T>
void HeapSort(T* arr, size_t size)
{
assert(arr);
for (int i = (size - 2) / 2; i >= 0; i--) //建小堆
{
Adjustdown(arr, i, size);
}
size_t end = size - 1;
while (end > 0)
{
swap(arr[0], arr[end]);
Adjustdown(arr, 0, end);
end--;
}
};
template<class T>
void print(T* arr,size_t size)
{
for (int i = 0; i < size; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void TestHeapSort()
{
int a[] = {7,1,0,5,8,2};
HeapSort(a, sizeof(a)/sizeof(a[0]));
print(a, sizeof(a) / sizeof(a[0]));
}