64,654
社区成员
发帖
与我相关
我的任务
分享
#include <stdexcept>
#include <iostream>
#include <vector>
using namespace std;
namespace MyHeap{
/****************************STL风格****************************/
//默认比较Functor
template<class HeapNode>
class DefaultCmpOpr{
public:
inline bool operator()(const HeapNode& lhs,const HeapNode& rhs){return lhs>rhs;}
};
//默认交换操作函数对象
template<class HeapNode>
class DefaultSwapDo{
public:
inline void operator()(HeapNode& lhs,HeapNode& rhs){::swap(lhs,rhs);}
};
template<class RandomItr>
inline RandomItr Parent(RandomItr begin,RandomItr index){
return begin+(index-begin-1)/2;
}
template<class RandomItr>
inline RandomItr Left(RandomItr begin,RandomItr index){
return begin+(index-begin)*2+1;
}
template<class RandomItr>
inline RandomItr Right(RandomItr begin,RandomItr index){
return begin+(index-begin)*2+2;
}
//堆上浮
template<class RandomItr,
class CmpOpr,
class SwapDo>
void HeapUp(RandomItr begin,RandomItr end,
RandomItr index,
CmpOpr cmp=DefaultCmpOpr(),SwapDo sd=DefaultSwapDo());
//堆下沉
template<class RandomItr,
class CmpOpr,
class SwapDo>
void HeapDown(RandomItr begin,RandomItr end,
RandomItr index,
CmpOpr cmp=DefaultCmpOpr(),SwapDo sd=DefaultSwapDo());
//出堆
template<class RandomItr,
class CmpOpr,
class SwapDo>
void PopHeap(RandomItr begin,RandomItr end,
CmpOpr cmp=DefaultCmpOpr(),SwapDo sd=DefaultSwapDo());
//入堆
template<class HeapNode,
class RandomItr,
class CmpOpr,
class SwapDo>
void PushHeap(RandomItr begin,RandomItr end,
const HeapNode& newNode,
CmpOpr cmp=DefaultCmpOpr(),SwapDo sd=DefaultSwapDo());
//制作堆
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MakeHeap(RandomItr begin,RandomItr end,
CmpOpr cmp=DefaultCmpOpr(),SwapDo sd=DefaultSwapDo());
//判断是否是堆
template<class RandomItr,
class CmpOpr>
bool IsHeap(RandomItr begin,RandomItr end,CmpOpr cmp=DefaultCmpOpr());
//堆排序
template<class RandomItr,
class CmpOpr,
class SwapDo>
void SortHeap(RandomItr begin,RandomItr end,
CmpOpr cmp,SwapDo sd);
/******************************以下为使用Demo******************************/
void TestSTLHeap(){
using namespace std;
std::vector<int> heap;
const int N=10;
const int MAX=100;
for(int i=0;i<N;++i){
heap.push_back(rand()%MAX);
}
SortHeap(heap.begin(),heap.end(),DefaultCmpOpr<int>(),DefaultSwapDo<int>());
cout<<"Sorted "<<endl;
for(int i=0;i<N;++i){
cout<<heap[i]<<" "<<endl;
}
}
}
/****************************************STL风格************************************/
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::HeapUp(RandomItr begin,RandomItr end,
RandomItr index,
CmpOpr cmp,SwapDo sd){
RandomItr parItr=Parent(begin,index);
while(parItr>=begin && cmp(*index,*parItr)){
sd(*index,*parItr);
index=parItr;
parIdx=Parent(begin,index);
}
}
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::HeapDown(RandomItr begin,RandomItr end,
RandomItr index,
CmpOpr cmp,SwapDo sd){
RandomItr sonItr=Left(begin,index);
while(sonItr<end){
//找到最大儿子
if(sonItr+1<end && cmp(*(sonItr+1),*sonItr)){
++sonItr;
}
if(cmp(*sonItr,*index)){
sd(*sonItr,*index);//do after swapping
//继续向下寻找
index=sonItr;
sonItr=Left(begin,index);
}else{
return;
}
}
}
//STL风格
//逻辑上的heap大小减小1,但是容器的大小不变
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::PopHeap(RandomItr begin,RandomItr end,
CmpOpr cmp,SwapDo sd){
if(begin==end){
return;
}
--end;
sd(*begin,*end);//do after swapping
HeapDown(begin,end,begin,cmp,sd);//stl 风格
}
//容器的真实大小必须大于逻辑大小
//入堆
template<class HeapNode,
class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::PushHeap(RandomItr begin,RandomItr end,
const HeapNode& newNode,
CmpOpr cmp,SwapDo sd){
*end=newNode;
++end;
HeapUp(begin,end,end-1,cmp,sd);
}
//制作堆
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::MakeHeap(RandomItr begin,RandomItr end,
CmpOpr cmp,SwapDo sd){
for(RandomItr itr=begin+(end-begin)/2-1;itr>=begin;--itr){
HeapDown(begin,end,itr,cmp,sd);
}
}
//判断是否是堆
template<class RandomItr,
class CmpOpr>
bool MyHeap::IsHeap(RandomItr begin,RandomItr end,CmpOpr cmp){
for(RandomItr itr=begin+(end-begin)/2-1;itr>=begin;--itr){
if(cmp(*itr,*Left(begin,itr))){
return false;
}
if(Right(begin,itr)<end && cmp(*itr,*Right(begin,itr))){
return false;
}
}
return true;
}
//堆排序
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::SortHeap(RandomItr begin,RandomItr end,
CmpOpr cmp,SwapDo sd){
//建堆
MakeHeap(begin,end,cmp,sd);
//排序
for(RandomItr newEnd=end-1;newEnd>=begin+1;--newEnd){
sd(*newEnd,*begin);
HeapDown(begin,newEnd,begin,cmp,sd);
}
}
void main(){
MyHeap::TestSTLHeap();
system("pause");
}
#include <stdexcept>
#include <iostream>
#include <vector>
using namespace std;
namespace MyHeap{
/****************************STL风格****************************/
//默认比较Functor
template<class HeapNode>
class DefaultCmpOpr{
public:
inline bool operator()(const HeapNode& lhs,const HeapNode& rhs){return lhs>rhs;}
};
//默认交换操作函数对象
template<class HeapNode>
class DefaultSwapDo{
public:
inline void operator()(HeapNode& lhs,HeapNode& rhs){::swap(lhs,rhs);}
};
template<class RandomItr>
inline RandomItr Parent(RandomItr begin,RandomItr index){
return begin+(index-begin-1)/2;
}
template<class RandomItr>
inline RandomItr Left(RandomItr begin,RandomItr index){
return begin+(index-begin)*2+1;
}
template<class RandomItr>
inline RandomItr Right(RandomItr begin,RandomItr index){
return begin+(index-begin)*2+2;
}
//堆上浮
template<class RandomItr,
class CmpOpr,
class SwapDo>
void HeapUp(RandomItr begin,RandomItr end,
RandomItr index,
CmpOpr cmp,SwapDo sd);
//堆下沉
template<class RandomItr,
class CmpOpr,
class SwapDo>
void HeapDown(RandomItr begin,RandomItr end,
RandomItr index,
CmpOpr cmp,SwapDo sd);
//出堆
template<class RandomItr,
class CmpOpr,
class SwapDo>
void PopHeap(RandomItr begin,RandomItr end,
CmpOpr cmp,SwapDo sd);
//入堆
template<class HeapNode,
class RandomItr,
class CmpOpr,
class SwapDo>
void PushHeap(RandomItr begin,RandomItr end,
const HeapNode& newNode,
CmpOpr cmp,SwapDo sd);
//制作堆
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MakeHeap(RandomItr begin,RandomItr end,
CmpOpr,SwapDo sd);
//判断是否是堆
template<class RandomItr,
class CmpOpr>
bool IsHeap(RandomItr begin,RandomItr end,CmpOpr cmp);
//堆排序
template<class RandomItr,
class CmpOpr,
class SwapDo>
void SortHeap(RandomItr begin,RandomItr end,
CmpOpr cmp,SwapDo sd);
/******************************以下为使用Demo******************************/
void TestSTLHeap(){
using namespace std;
std::vector<int> heap;
const int N=10;
const int MAX=100;
for(int i=0;i<N;++i){
heap.push_back(rand()%MAX);
}
SortHeap(heap.begin(),heap.end(),DefaultCmpOpr<int>(),DefaultSwapDo<int>());
cout<<"Sorted "<<endl;
for(int i=0;i<N;++i){
cout<<heap[i]<<" "<<endl;
}
}
}
/****************************************STL风格************************************/
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::HeapUp(RandomItr begin,RandomItr end,
RandomItr index,
CmpOpr cmp,SwapDo sd){
RandomItr parItr=Parent(begin,index);
while(parItr>=begin && cmp(*index,*parItr)){
sd(*index,*parItr);
index=parItr;
parItr=Parent(begin,index);
}
}
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::HeapDown(RandomItr begin,RandomItr end,
RandomItr index,
CmpOpr cmp,SwapDo sd){
RandomItr sonItr=Left(begin,index);
while(sonItr<end){
//找到最大儿子
if(sonItr+1<end && cmp(*(sonItr+1),*sonItr)){
++sonItr;
}
if(cmp(*sonItr,*index)){
sd(*sonItr,*index);//do after swapping
//继续向下寻找
index=sonItr;
sonItr=Left(begin,index);
}else{
return;
}
}
}
//STL风格
//逻辑上的heap大小减小1,但是容器的大小不变
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::PopHeap(RandomItr begin,RandomItr end,
CmpOpr cmp,SwapDo sd){
if(begin==end){
return;
}
--end;
sd(*begin,*end);//do after swapping
HeapDown(begin,end,begin,cmp,sd);//stl 风格
}
//容器的真实大小必须大于逻辑大小
//入堆
template<class HeapNode,
class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::PushHeap(RandomItr begin,RandomItr end,
const HeapNode& newNode,
CmpOpr cmp,SwapDo sd){
*end=newNode;
++end;
HeapUp(begin,end,end-1,cmp,sd);
}
//制作堆
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::MakeHeap(RandomItr begin,RandomItr end,
CmpOpr cmp,SwapDo sd){
for(RandomItr itr=begin+(end-begin)/2-1;itr>=begin;--itr){
HeapDown(begin,end,itr,cmp,sd);
}
}
//判断是否是堆
template<class RandomItr,
class CmpOpr>
bool MyHeap::IsHeap(RandomItr begin,RandomItr end,CmpOpr cmp){
for(RandomItr itr=begin+(end-begin)/2-1;itr>=begin;--itr){
if(cmp(*itr,*Left(begin,itr))){
return false;
}
if(Right(begin,itr)<end && cmp(*itr,*Right(begin,itr))){
return false;
}
}
return true;
}
//堆排序
template<class RandomItr,
class CmpOpr,
class SwapDo>
void MyHeap::SortHeap(RandomItr begin,RandomItr end,
CmpOpr cmp,SwapDo sd){
//建堆
MakeHeap(begin,end,cmp,sd);
//排序
for(RandomItr newEnd=end-1;newEnd>=begin+1;--newEnd){
sd(*newEnd,*begin);
HeapDown(begin,newEnd,begin,cmp,sd);
}
}
int main(){
MyHeap::TestSTLHeap();
system("pause");
return 0;
}