#pragma once
#include<iostream>
#include<vector>
using namespace std;
class BigHeap//仿函数类 大堆返回true
{
public:
bool operator()()
{
return true;
}
};
class SmallHeap//仿函数类 小堆返回false
{
public:
bool operator()()
{
return false;
}
};
template <class T,class BigOrSmall>//BigOrSmall为实例化对象时传入模板类型 大堆或小堆
class Heap
{
public:
vector<T> _array;
BigOrSmall _isBigHeap;//通过实例对象 _isBigHeap 调用BigHeap或SmallHeap的operator() 得到不同Bool值来区分大堆小堆
public:
Heap()
{}
Heap(int* a,size_t size)
{
for (size_t i = 0; i < size; ++i)
{
_array.push_back(a[i]);
}
{
for (size_t i = (_array.size() - 2) / 2; i >= 0; --i)
{
AdjustDown(i);
if (i == 0)
break;
}
}
}
void Push(T data)
{
_array.push_back(data);
AdjustUp(_array.size()-1);
}
void Pop()
{
swap(_array[0], _array[_array.size() - 1]);
AdjustDown(0);
_array.pop_back();
}
void HeapSort()//堆排序 O(n *Log* n)
{
size_t i = 0;//
if (_isBigHeap())//判断大小堆
{
while (i < _array.size()-1)//i从0 循环
{
if (_array[i] < _array[i + 1])//每次左右交换
swap(_array[i], _array[i + 1]);
AdjustDown(i);//之后向下调整
++i;
}
}
else
{
while (i < _array.size() - 1)
{
if (_array[i] > _array[i + 1])
swap(_array[i], _array[i + 1]);
AdjustDown(i);
++i;
}
}
}
protected:
void AdjustDown(size_t index)//向下调整 初始化时用
{
while (index < _array.size()-1)
{
if (!_isBigHeap())//调用仿函数
{
if ((index * 2 + 2)<=_array.size() - 1 && _array[index * 2 + 1]>_array[index * 2 + 2])
swap(_array[index * 2 + 1], _array[index * 2 + 2]);
if ((index * 2 + 1)<=_array.size() - 1 && _array[index] > _array[index * 2 + 1])
swap(_array[index], _array[index * 2 + 1]);
}
else
{
if ((index * 2 + 2)<=_array.size() - 1 && _array[index * 2 + 1]<_array[index * 2 + 2])
swap(_array[index * 2 + 1], _array[index * 2 + 2]);
if ((index * 2 + 1)<=_array.size() - 1 && _array[index] <_array[index * 2 + 1])
swap(_array[index], _array[index * 2 + 1]);
}
index = index * 2 + 1;
}
}
//向上调整 每次push时用
void AdjustUp(size_t index)
{
while (index!=0)
{
size_t i = (index-1)/2;
if (!_isBigHeap())
{
if (index + 1 < _array.size() && _array[index] > _array[index + 1])
swap(_array[index], _array[index + 1]);
if (_array[i] > _array[index])
swap(_array[i], _array[index]);
else
break;
}
else
{
if (index + 1 < _array.size() && _array[index] < _array[index + 1])
swap(_array[index], _array[index + 1]);
if (_array[i] < _array[index])
swap(_array[i], _array[index]);
else
break;
}
index = i;
}
}
};
#include"heap.hpp"//测试用例
using namespace std;
void test()
{
int a[10] = { 10, 16, 18, 12, 11, 13, 15, 17, 14, 19 };
Heap<int,SmallHeap> h1(a, 10);
Heap<int, BigHeap> h2(a, 10);
h1.Push(1);
h1.Pop();
h1.HeapSort();
}
int main()
{
test();
return 0;
}
转载于:https://blog.51cto.com/shaungqiran/1753148