这里借助此前业已实现的Vector数据结构来实现一个最大堆,可以看到这里大量的使用了宏,目的是使得后面的操作更加的简明,这样一来在读这段代码的时候就不会一味的拘泥于某些子功能的实现逻辑,而将目光转向实际的算法当中去。(当然这里的代码实现也是参考清华大学邓俊辉教授的教材,值得注意的是如果完全按照示例代码包的实现方式,不仅是的这段代码晦涩难懂,就算是在测试的过程中也是一头雾水,所以在这里我采取了这种的策略,适当的修改了教材以及事例代码包中的代码,并且将其實現,供大家参考)最重要的一点是去真正的领会堆的含义,以及各种作用在它之上的不同操作的实现细节。
#include"Vector.h"
#define InHeap(n,i) (((-1)<i))&&((i)<(n))
#define Parent(i) ((i-1)>>1)
#define LastInternal(n) Parent(n-1)
#define LChild(i) (1+((i)<<1))
#define RChild(i) ((1+(i)<<1))
#define ParentValid(i) (0<i)
#define LChildValid(n,i) InHeap(n,LChild(i))
#define RChildValid(n,i) InHeap(n,RChild(i))
#define Bigger(PQ,i,j) (lt(PQ[i],PQ[j])?j:i)
#define ProperParent(PQ,n,i) \
(RChildValid(n,i)?Bigger(PQ,Bigger(PQ,i,LChild(i)),RChild(i)):\
(LChildValid(n,i)?Bigger(PQ,i,LChild(i)):i\
)\
)
template<typename T>
struct PQ
{
virtual void insert(T) = 0;
virtual T getMax() = 0;
virtual T delMax() = 0;
};
template<typename T>
class PQ_ComplHeap :public PQ<T>, public Vector<T>
{
protected:
Rank percolateDown(Rank n, Rank i);
Rank percolateUp(Rank i);
void heapify(Rank n);
public:
PQ_ComplHeap()
{
}
PQ_ComplHeap(T* A, Rank n)
{
Vector<T>::copyFrom(A, 0, n);
heapify(n);
}
void insert(T e);
T getMax();
T delMax();
};
template<typename T>
T PQ_ComplHeap<T>::getMax()
{
return Vector<T>::_elem[0];
}
template<typename T>
void PQ_ComplHeap<T>::insert(T e)
{
Vector<T>::insert(e);
percolateUp(Vector<T>::_size - 1);
}
template<typename T>
Rank PQ_ComplHeap<T>::percolateUp(Rank i)
{
while (ParentValid(i))
{
Rank j = Parent(i);
if (lt(Vector<T>::_elem[i], Vector<T>::_elem[j]))
{
break;
}
else
{
swap(Vector<T>::_elem[i], Vector<T>::_elem[j]);
i = j;
}
}
return i;
}
template<typename T>
T PQ_ComplHeap<T>::delMax()
{
T maxElem = Vector<T>::_elem[0];
Vector<T>::_elem[0] = Vector<T>::_elem[--Vector<T>::_size];
percolateDown(Vector<T>::_size, 0);
return maxElem;
}
template<typename T>
Rank PQ_ComplHeap<T>::percolateDown(Rank n, Rank i)
{
Rank j;
while (i != (j = ProperParent(this->_elem, n, i)))
{
std::swap(Vector<T>::_elem[i], Vector<T>::_elem[j]);
i = j;
}
return i;
}
template<typename T>
void PQ_ComplHeap<T>::heapify(Rank n)
{
for (int i = LastInternal(n); InHeap(n, i); i--)
{
percolateDown(n, i);
}
}
template<typename T>
void Vector<T>::heapSort(Rank lo, Rank hi)
{
PQ_ComplHeap<T>H(Vector<T>::_elem + lo, hi - lo);
while (!H.Vector<T>::empty())
{
Vector<T>::_elem[--hi] = H.delMax();
}
}
int main()
{
Vector<int>obj;
for (int i = 0; i < 100;i++)
{
obj.insert(i);
}
obj.unsort();
obj.traverse(visit);
cout << endl;
obj.heapSort(0, 100);
obj.traverse(visit);
system("pause");
return 0;
}
关于Floyd建堆算法,大部分教科书上不会提及算法的名字,但是,从最后一个非叶节点开始建堆的过程实际上就是Floyd建堆算法,这里不要将名字与图论算法中的Floyd-Warshall算法混为一谈!