堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构。
堆结构的二叉树存储是
最大堆:每个父节点的都大于孩子节点。
最小堆:每个父节点的都小于孩子节点。
代码如下:
#include<iostream>
#include<vector>
#include<assert.h>
using namespace std;
//最大堆:每个父节点的值都大于孩子节点
//最大堆:每个父节点的值都小于孩子节点
//仿函数来确定创建大堆还是小堆
template<class T>
class Less
{
public:
bool operator()(const T& l, const T& r)
{
return l < r;
}
};
template<class T>
class Greater
{
public:
bool operator()(const T& l, const T& r)
{
return l > r;
}
};
template<class T,template<class> class Compare = Less>
class Heap
{
public:
Heap()
{}
Heap(const T* arr, size_t size)
{
assert(arr);
//插入节点
for (size_t i = 0;i < size;++i)
{
_arr.push_back(arr[i]);
}
//向下调整n*logn
for (int i = (_arr.size() - 2) / 2;i >= 0;--i)
{
_AdjustDown(i);
}
}
protected:
void _AdjustDown(size_t parent)
{
size_t child = parent * 2 + 1;
while (child <_arr.size())
{
if(child+1<_arr.size() && Compare<T>()(_arr[child+1],_arr[child]))
++child;
//if (_arr[child]<_arr[parent])
if(Compare<T>()(_arr[child],_arr[parent]))
{
swap(_arr[child],_arr[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void _AdjustUp(size_t child)
{
int parent = (child - 1) / 2;
while (child > 0)
{
//if (_arr[child] > _arr[parent])
if(Compare<T>()(_arr[child],_arr[parent]))
{
swap(_arr[child], _arr[parent]);
child = parent;
parent= (child - 1) / 2;
}
else
{
break;
}
}
}
public:
void Push(const T& x)
{
_arr.push_back(x);
_AdjustUp(_arr.size()-1);
}
void Pop()
{
_arr.pop_back();
}
private:
vector<T> _arr;
};
(1)优先级队列,分装大堆小堆。
(2)100w中最大的k个数,建立的是小堆,每次进入一个数,与堆顶比较,大于堆顶交换数据,向下调整堆,遍历完数据后堆内数据即是。
(3)2015年春节期间,A公司的支付软件某宝和T公司某信红包大乱战。春节后高峰以后,公司Leader要求后台的攻城狮对后台的海量数据进行分析。先要求分析出各地区发红包金额最多的前100用户。现在知道人数最多的s地区大约有1000w用户。要求写一个算法实现。
【扩展:海量数据处理】
const int N = 1000000;
const int K = 100;
void GetTopK(int a[])
{
assert(K < N);
int topK[K];
for (int i = 0;i < K;++i)
{
topK[i] = a[i];
}
//建小堆
for (int j = (K - 2) / 2;j >= 0;--j)
{
_AdjustDown(topK, K, j);
}
int count = K;
while (count < N)
{
if (a[count]>a[0])
{
swap(a[count],a[0]);
_AdjustDown(a, K, 0);
}
count++;
}
}
//(4)堆排序,递增序列建立大堆,
void _AdjustDown(int *_arr,int n,int parent)
{
int child = parent * 2 + 1;
while (child <n)
{
if (child + 1 < n && _arr[child + 1] > _arr[child])
++child;
if (_arr[child]>_arr[parent])
{
swap(_arr[child], _arr[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void Heapsort(int *arr, int len)
{
assert(arr!=NULL && len>=0);
for (int i = (len - 2) / 2;i >= 0;--i)
{
_AdjustDown(arr, len, i);
}
for (int j = 0;j < len;++j)
{
swap(arr[0], arr[len - 1 - j]);
_AdjustDown(arr, len - j - 1, 0);
}
}