小根堆,大根堆,堆排序

小根堆,大根堆,堆排序

下面用c++模板实现小根堆,大根堆,堆排序功能, 可以适用不同类型的数据,可以直接使用

//file:heap.h

#ifndef _AGILE_HEAP_H_
#define _AGILE_HEAP_H_

#include <iostream>
#include <vector>
//等于比较函数
typedef bool(*EqualFunc)(void*, void*);

//比较两个数,返回最大那个
typedef void* (*GetGreaterFunc)(void*, void*);
//堆代理类
template<typename Type>
class  AgileHeapDelegate
{
public:
AgileHeapDelegate()
{

};

virtual ~AgileHeapDelegate()
{
};
//建立一个新堆
virtual void BuildHeapExt(std::vector<Type>& aHeap, size_t size)
{
int mid = (int)(size / 2);
while (mid > -1)
{
size_t left = mid * 2 + 1;
size_t right = mid * 2 + 2;
SwapExt(aHeap, size, mid--, left, right);
}
};
//设置比较函数
virtual void SetCompareFun(GetGreaterFunc func) = 0;

protected:

//根据比较函数或者根据默认方式进行比较数组的两个数
virtual void Compare(std::vector<Type>& aHeap, size_t& what, size_t target) = 0;

//交换数组的数据

virtual void SwapExt(std::vector<Type>& aHeap, size_t size, size_t mid, size_t left, size_t right) = 0;
};

//堆的基类
template<typename Value>
class  AgileHeap
{
public:
AgileHeap()
{
};

virtual ~AgileHeap() 
{
};
//建堆纯虚函数
virtual void BuildHeap() = 0;
//添加一个数据,并在添加后重建堆
virtual void AddValueProcess(Value val)
{
_heap.push_back(val);
BuildHeap();
};
//添加一个数据
void AddValue(Value val)
{
_heap.push_back(val);
};
//删除一个数据,并在删除后重建堆
virtual bool DeleteValueProcess(Value val)
{
if (DeleteValue(val))
{
BuildHeap();
return true;
}
return false;
};

//通过比较函数或者默认比较来删除数据
virtual bool DeleteValue(Value val)
{
for (size_t i = 0; i < _heap.size(); i++)
{
if ( ( _equal.valid && (*_equal.func)(&_heap[i], &val) ) || val == _heap[i])
{
_heap[i] = _heap.back();
_heap.pop_back();
return true;
}
}
return false;
};
//获取堆顶数据
Value GetTop()
{
return _heap.front();
};
//抛出堆顶数据,并重建堆
virtual Value PopTopProcess()
{
Value val = PopTop();
BuildHeap();
return val;
};

//抛出堆顶数据
Value PopTop()
{
Value header = _heap.front();
if (_heap.size() > 1)
{
_heap[0] = _heap.back();
_heap.pop_back();
}
else if ( 1 == _heap.size())
{
_heap.pop_back();
}
return header;
};
//获取堆底数据
Value GetBottom()
{
return _heap.back();
};
//抛出堆底数据,并重建堆
virtual Value PopBottomProcess()
{
Value val = PopBottom();
BuildHeap();
return val;
};
//抛出堆底数据
Value PopBottom()
{
Value back = _heap.back();
if (_heap.size() > 0)
{
_heap.pop_back();
}
return back;
};
//获取整个堆数据
std::vector<Value>* GetAll() const
{
return &_heap;
};
//设置等于函数
void SetEqualFun(EqualFunc func)
{
_equal.func = func;
_equal.valid = true;
};

protected:
//交换数据
void Swap(std::vector<Value>& aHeap, size_t dest, size_t src)
{
Value temp = aHeap[dest];
aHeap[dest] = aHeap[src];
aHeap[src] = temp;
};

protected:
//比较函数结构体
struct CompareFun
{
bool valid;
EqualFunc func;
GetGreaterFunc greater;
CompareFun() :valid(false)
{
};
};

CompareFun _equal;
std::vector<Value> _heap;
};
//小根堆实现
template<typename Type>
class  AgileMinHeap : public AgileHeap<Type>, public AgileHeapDelegate<Type>
{
public:
AgileMinHeap()
{
};

virtual ~AgileMinHeap()
{
};

virtual void BuildHeap()
{
BuildHeapExt(_heap, _heap.size());
};

virtual void SetCompareFun(GetGreaterFunc func)
{
_less.greater = func;
_less.valid = true;
};

protected:

virtual void Compare(std::vector<Type>& aHeap, size_t& what, size_t target)
{
if (_less.valid) //如果设置了比较函数
{
if (&aHeap[what] == (*_less.greater)(&aHeap[what], &aHeap[target]))
{
what = target;
}
}
else
{
if (aHeap[what] > aHeap[target])
{
what = target;
}
}
};

virtual void SwapExt(std::vector<Type>& aHeap, size_t size, size_t mid, size_t left, size_t right)
{
size_t what = mid;
if (left < size)
{
Compare(aHeap, what, left);
}
if (right < size)
{
Compare(aHeap, what, right);
}
if (what != mid)
{
Swap(aHeap, mid, what);//交换mid和what位置的数据
}
};

private:
CompareFun _less;
};

//大根堆实现
template<typename Type>
class  AgileMaxHeap : public AgileHeap<Type>, public AgileHeapDelegate<Type>
{
public:
AgileMaxHeap()
{
};

virtual ~AgileMaxHeap()
{
};

virtual void BuildHeap()
{
BuildHeapExt(_heap, _heap.size());
};

virtual void SetCompareFun(GetGreaterFunc func)
{
_greater.greater = func;
_greater.valid = true;
};

protected:
virtual void Compare(std::vector<Type>& aHeap, size_t& what, size_t target)
{

//如果设置了比较函数
if (_greater.valid)
{
if (&aHeap[target] == (*_greater.greater)(&aHeap[what], &aHeap[target]))
{
what = target;  //记录下索引
}
}
else
{
if (aHeap[what] < aHeap[target])
{
what = target;//记录下索引
}
}
};

virtual void SwapExt(std::vector<Type>& aHeap, size_t size, size_t mid, size_t left, size_t right)
{
size_t what = mid;
if (left < size)
{
Compare(aHeap, what, left);
}
if (right < size)
{
Compare(aHeap, what, right);
}
if (what != mid) 
{
Swap(aHeap, mid, what); //交换mid和what位置的数据
}
};

private:
CompareFun _greater;
};

//有序堆
template<typename Type>
class  AgileSortHeap : public AgileHeap<Type>
{
public:
AgileSortHeap()
{
_isAscend = true;
InitDelegate();
};
//isAscend是否是升序
AgileSortHeap(bool isAscend)
{
_isAscend = isAscend;
InitDelegate();
};

virtual ~AgileSortHeap()
{


};

virtual void BuildHeap()
{
_delegate->BuildHeapExt(_heap, _heap.size() );
};
//进行堆排序
virtual void Sort()
{
size_t size = _heap.size();
while (size > 1)
{
_delegate->BuildHeapExt(_heap, size--);
Swap(_heap, 0, size);
}
};

virtual void SetCompareFun(GetGreaterFunc func)
{
_compare.greater = func;
_compare.valid = true;
_delegate->SetCompareFun(func);
};

//添加数据后,并进行堆排序
virtual void AddValueProcess(Type val)
{
_heap.push_back(val);
Sort();
};
//删除数据后,并进行堆排序
virtual bool DeleteValueProcess(Type val)
{
if ( DeleteValue(val) )
{
Sort();
return true;
}
return false;
};
//通过二分查找删除数据
virtual bool DeleteValue(Type val)
{
size_t low = 0;
size_t high = _heap.size() - 1;
size_t mid = (high + low) / 2;


while ( low <= high)
{
if ( (_equal.valid && (*_equal.func)(&_heap[mid], &val)) || val == _heap[mid] )
{
break;
}
if (_isAscend)
{
if (_compare.valid)
{
if ( &val==(*_compare.greater)(&_heap[mid], &val))
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
else
{
if (_heap[mid] < val)
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
}
else
{
if (_compare.valid)
{
if (&val==(*_compare.greater)(&_heap[mid], &val))
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
else
{
if (_heap[mid] < val)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
}
mid = (high + low) / 2;
}

if (low <= high)
{
_heap[mid] = _heap.back();
_heap.pop_back();
return true;
}
return false;
}; 

virtual Type PopTopProcess()
{
Type val = PopTop();
Sort();
return val;
};

virtual Type PopBottomProcess()
{
Type val = PopBottom();
Sort();
return val;
};
//初始化代理方式
private:
void InitDelegate()
{
if (_isAscend)
{
static AgileMaxHeap<Type> sHeap;
_delegate = &sHeap;  //升序初始化为大根堆
}
else
{
static AgileMinHeap<Type> sHeap;
_delegate = &sHeap;//降序初始化为小根堆
}
};

private:
bool _isAscend;
CompareFun _compare;
AgileHeapDelegate<Type>* _delegate;
};

#endif//_AGILE_HEAP_H_


//

使用例子

struct HeapData
{
int age;
string name;
HeapData() :age(0), name(""){};
HeapData(int a, string b) :age(a), name(b){};

bool operator < (const HeapData& arg)
{
return age < arg.age ? true : false;
};

bool operator > (const HeapData& arg)
{
return age > arg.age ? true : false;
};

bool operator == (const HeapData& arg)
{
return age == arg.age ? true : false;
};

void Desc() const
{
printf("age:%d -- name:%s\n", age, name.c_str());
}
};


void* testHeapCompare(void* obj1, void* obj2)
{
HeapData* obj11 = *(HeapData**)obj1;
HeapData* obj22 = *(HeapData**)obj2;
return obj11->age < obj22->age ? obj1 : obj2;
}

bool testHeapCompareEE(void* obj1, void* obj2)
{
HeapData* obj11 = **(HeapData***)obj1;
HeapData* obj22 = **(HeapData***)obj2;
return obj11->age == obj22->age ? true : false;
}

void testForHeap()
{
vector<HeapData*> newData;
for (size_t i = 0; i < 10; i++)
{
int numm = GetRandomNum(100);
HeapData* val = new HeapData(numm, "ok");
val->Desc();
newData.push_back(val);
}
printf("--------------------------------------------------\n");


AgileSortHeap<HeapData*> heap(true);
heap.SetCompareFun(&testHeapCompare);
heap.SetEqualFun(&testHeapCompareEE);


for (size_t i = 0; i < newData.size(); i++)
{
heap.AddValue(newData[i]);
}


heap.Sort();


vector<HeapData*>* ret = (vector<HeapData*>*)heap.GetAll();
for (size_t i = 0; i < ret->size(); i++)
{
(*ret)[i]->Desc();
}

for (size_t i = 0; i < 10; i++)
{
delete newData[i];
}

printf("\n");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值