"2.h"
#include<iostream>
#include<vector>
#include<assert.h>
using namespace std;
template<class T>
struct Less
{
bool operator()(const T& left,const T& right)
{
return left<right;
}
};
template<class T>
struct Greater
{
bool operator()(const T& left,const T& right)
{
return left>right;
}
};
template<class T,class Compare=Less<T>>//小堆//修改
class Heap
{
public:
Heap();
Heap(const T* a,size_t size);
void Push(const T& x);
void Pop();
T& Top();
void Print();
void HeapSort();
void HeapSort1();
protected:
void AdjustDown(int parent);
void AdjustUp(int child);
void _AdjustDown(int child,int size);
private:
vector<T> _array;
Compare _compare;
};
template<class T,class Compare>
Heap<T,Compare>::Heap(const T* a,size_t size)
{
for(size_t i=0;i<size;i++)
{
_array.push_back(a[i]);
}
for(int i=(_array.size()-2)/2;i>=0;i--)//求父节点的下标为:((子-1)/2),
//而size()比最大下标多一,所以为减2
{
AdjustDown(i);
}
/*for(int i=_array.size()-1;i>0;i--)
{
AdjustUp(i);
}*/
}
template<class T,class Compare>
void Heap<T,Compare>::AdjustDown(int parent)
{
int child=parent*2+1;
while(child<_array.size())
{
if((child+1<_array.size())&&_compare(_array[child+1],_array[child]))//右孩子是否越界条件易忘
swap(_array[child],_array[child+1]);
if(Compare()(_array[child],_array[parent]))
{
swap(_array[child],_array[parent]);
parent=child;
child=parent*2+1;
}
else
break;
}
}
template<class T,class Compare>
void Heap<T,Compare>::AdjustUp(int child)
{
int parent=(child-1)/2;
while(child>0)//条件不能写成parent>=0,因为parent不可能小于0
{
if(child+1<_array.size()&&_compare(_array[child+1],_array[child]))
swap(_array[child],_array[child+1]);
if(Compare()(_array[child],_array[parent]))
{
swap(_array[child],_array[parent]);
child=parent;
parent=(child-1)/2;
}
else
break;
}
}
//插进来的放在最后的子节点位置
template<class T,class Compare>
void Heap<T,Compare>::Push(const T& x)//记住加上const和&
{
_array.push_back(x);
//AdjustDown(0); //想清楚可不可用AdjustDown(0); //不可以,主要看哪儿动了
AdjustUp(_array.size()-1);
}
//Pop出去的是根,下标为0
template<class T,class Compare>
void Heap<T,Compare>::Pop()
{
//
swap(_array[0],_array[_array.size()-1]);
_array.pop_back();
AdjustDown(0);
}
template<class T,class Compare>
T& Heap<T,Compare>::Top()
{
return _array[0];
}
template<class T,class Compare>
void Heap<T,Compare>::Print()
{
for(size_t i=0;i<_array.size();i++)
{
cout<<_array[i]<<" ";
}
cout<<endl;
}
//把堆排成大堆,交换堆顶和堆尾,每次除掉堆尾数据其余数据继续排成大堆...
//理解错误,虽然能实现堆排序,但误用AdjustUp(int child)(没去掉注释的两行)——向上排序
//只用于已排好二叉树进行插入时,少数数据的改变,不能在构造函数中直接用向上排序构造
template<class T,class Compare>
void Heap<T,Compare>::HeapSort()
{
for(int i=_array.size()-1;i>=0;i--)
{
for(int j=_array.size()-1;j>0;j--)//除掉堆尾数据有误
AdjustUp(j);
swap(_array[0],_array[i]);
}
}
//由于要改变size,所以得重建AdjustDown
template<class T,class Compare>
void Heap<T,Compare>::HeapSort1()
{
for(int size=_array.size();size>1;size--)
{
for(int i=(size-2)/2;i>=0;i--)
{
_AdjustDown(i,size);
}
swap(_array[0],_array[size-1]);
}
}
template<class T,class Compare>
void Heap<T,Compare>::_AdjustDown(int parent,int size)
{
int child=parent*2+1;
while(child<size)
{
if((child+1<size)&&_compare(_array[child+1],_array[child]))
swap(_array[child],_array[child+1]);
if(Compare()(_array[child],_array[parent]))
{
swap(_array[child],_array[parent]);
parent=child;
child=parent*2+1;
}
else
break;
}
}
#include "2.h"
#include<iostream>
using namespace std;
void Test1()
{
int a[]={1,2,9,5,8,7,4,3};
//Heap<int> hp1(a,8);
Heap<int,Greater<int>> hp1(a,8);
hp1.Print();
hp1.Push(0);
hp1.Print();
hp1.Pop();
hp1.Print();
int top=hp1.Top();
cout<<top<<endl;
hp1.HeapSort();
hp1.Print();
}
int main()
{
Test1();
system("pause");
return 0;
}
转载于:https://blog.51cto.com/10707460/1758170