昨天写完堆的代码后,今天又敲了一下,顺便用到了函数对象,可以指定生成最小/大堆.
(注释就懒得写了,有什么问题可以私下留言,或者看我上篇文章,毕竟本文仅供个人娱乐)
/*
*文件说明:堆的相关声明及实现(第二遍)
*作者:高小调
*日期:2016-12-27
*集成开发环境:Microsoft Visual Studio 2010
*/
#include<vector>
template<typename T>
struct Min{
bool operator()(T left,T right){
return left<right;
}
};
template<typename T>
struct Max{
bool operator()(T left,T right){
return left>right;
}
};
template<typename T,typename class Type = Min<T>>
class Heap{
public:
Heap(){}
Heap(T arr[],size_t sz)
:_a(arr,arr+sz){
size_t LastNotLeapNode = (_a.size()-2)/2;
for(int idx=LastNotLeapNode; idx>=0; --idx){
_AdjustDown(idx);
}
}
void Push(const T &e){
_a.push_back(e);
size_t LastNotLeapNode = (_a.size()-2)/2;
_AdjustUp(LastNotLeapNode);
}
void Pop(){
swap(_a[0],_a[_a.size()-1]);
_a.pop_back();
_AdjustDown(0);
}
protected:
void _AdjustDown(size_t idx){
size_t parent = idx;
size_t child = idx*2+1;
while(child<_a.size()){
if(child+1<_a.size() && Type()(_a[child+1],_a[child])){
++child;
}
if(Type()(_a[child],_a[parent])){
swap(_a[child],_a[parent]);
parent = child;
child = parent*2+1;
}else{
break;
}
}
}
void _AdjustUp(size_t idx){
size_t parent = idx;
size_t child = 2*idx+1;
while(child<_a.size() && child>parent){
if(child+1<_a.size() && Type()(_a[child+1] , _a[child])){
++child;
}
if(Type()(_a[child],_a[parent])){
swap(_a[child],_a[parent]);
child = parent;
parent = (child-1)/2;
}else{
break;
}
}
}
private:
vector<T> _a;
};
/*
*文件说明:测试文件
*作者:高小调
*日期:2016-12-26
*集成开发环境:Microsoft Visual Studio 2010
*/
#include<iostream>
using namespace std;
#include"Heap2.h"
void TestHeap(){
int arr[] = {10,16,18,12,11,13,15,17,14,19};
size_t sz = sizeof(arr)/sizeof(arr[0]);
Heap<int> h1(arr,sz); //小堆
Heap<int,Max<int>> h2(arr,sz); //大堆
h1.Pop();
h1.Push(5);
h2.Pop();
h2.Push(20);
}
int main(){
TestHeap();
return 0;
}
总结:
第二遍再去敲堆的时候,就行云流水多了,但还是犯了个小错误:在构造函数中,没有给_a初始化...
最基础的,就是最精华的!
继续努力!
原文:http://www.cnblogs.com/shujujiegou/p/6227202.html