堆排序算法,参考这里,其实了解了建堆的过程,排序的思路就清楚了!元素个数为n,调用n/2次调整就可以了!
这里给出优先级队列的代码,原理都差不多!
大顶堆:
template<typename T>
class MaxHeap
{
public:
MaxHeap(int size);
~MaxHeap();
void pop();
T top();
void push_back(T);
bool IsEmpty();
void Clear();
int size() { return _nCurSize; }
private:
void ShiftUp();
void ShiftDown();
void newCapacity();
int _nCapacity;
int _nCurSize;
T * _pData = NULL;
};
template<typename T>
MaxHeap<T>::MaxHeap(int size)
{
_nCapacity = size > 0 ? size : 0;
_nCurSize = 0;
_pData = new T[_nCapacity];
}
template<typename T>
MaxHeap<T>::~MaxHeap()
{
delete [] _pData;
}
template<typename T>
void MaxHeap<T>::pop()
{
_pData[0] = _pData[--_nCurSize];
ShiftDown();
}
template<typename T>
T MaxHeap<T>::top()
{
return _pData[0];
}
template<typename T>
void MaxHeap<T>::push_back(T elem)
{
if (_nCurSize == _nCapacity)
newCapacity(); //空间不足,重新申请
_pData[_nCurSize++] = elem;
ShiftUp();
}
template<typename T>
bool MaxHeap<T>::IsEmpty()
{
return _nCurSize == 0;
}
template<typename T>
void MaxHeap<T>::Clear()
{
_nCurSize = 0;
}
template<typename T>
void MaxHeap<T>::newCapacity()
{
_nCapacity *= 2;
T* newBuf = new T[_nCapacity];
memcpy(newBuf, _pData, _nCurSize*sizeof(T));
delete[] _pData;
_pData = newBuf;
}
template<typename T>
void MaxHeap<T>::ShiftDown()
{
int i = 0, j = i * 2 + 1;
T tmp = _pData[0];
while (j<_nCurSize)
{
if (j < _nCurSize-1 && _pData[j] < _pData[j + 1])
++j;
if (tmp >= _pData[j])
break;
else
{
_pData[i] = _pData[j];
i = j;
j = j * 2 + 1;
}
}
_pData[i] = tmp;
}
template<typename T>
void MaxHeap<T>::ShiftUp()
{
int j = _nCurSize - 1, i = (j-1)/2;
T tmp = _pData[j];
while (j>0)
{
if (_pData[i] >= tmp) break;
else {
_pData[j] = _pData[i];
j = i;
i = (i - 1) / 2;
}
}
_pData[j] = tmp;
}
小顶堆的代码:
template<class T>
class MinHeap
{
private:
T *heap; //元素数组,0号位置也储存元素
int CurrentSize; //目前元素个数
int MaxSize; //可容纳的最多元素个数
void FilterDown(const int start, const int end); //自上往下调整,使关键字小的节点在上
void FilterUp(int start); //自下往上调整
public:
MinHeap(int n = 1000);
~MinHeap();
bool Insert(const T &x); //插入元素
T RemoveMin(); //删除最小元素
T GetMin(); //取最小元素
bool IsEmpty() const;
bool IsFull() const;
void Clear();
};
template<class T>
MinHeap<T>::MinHeap(int n)
{
MaxSize = n;
heap = new T[MaxSize];
CurrentSize = 0;
}
template<class T>
MinHeap<T>::~MinHeap()
{
delete[]heap;
}
template<class T>
void MinHeap<T>::FilterUp(int start) //自下往上调整
{
int j = start, i = (j - 1) / 2; //i指向j的双亲节点
T temp = heap[j];
while (j>0)
{
if (heap[i] <= temp)
break;
else
{
heap[j] = heap[i];
j = i;
i = (i - 1) / 2;
}
}
heap[j] = temp;
}
template<class T>
void MinHeap<T>::FilterDown(const int start, const int end) //自上往下调整,使关键字小的节点在上
{
int i = start, j = 2 * i + 1;
T temp = heap[i];
while (j <= end)
{
if ((j<end) && (heap[j]>heap[j + 1]))
j++;
if (temp <= heap[j])
break;
else
{
heap[i] = heap[j];
i = j;
j = 2 * j + 1;
}
}
heap[i] = temp;
}
template<class T>
bool MinHeap<T>::Insert(const T &x)
{
if (CurrentSize == MaxSize)
return false;
heap[CurrentSize] = x;
FilterUp(CurrentSize);
CurrentSize++;
return true;
}
template<class T>
T MinHeap<T>::RemoveMin()
{
T x = heap[0];
heap[0] = heap[CurrentSize - 1];
CurrentSize--;
FilterDown(0, CurrentSize - 1); //调整新的根节点
return x;
}
template<class T>
T MinHeap<T>::GetMin()
{
return heap[0];
}
template<class T>
bool MinHeap<T>::IsEmpty() const
{
return CurrentSize == 0;
}
template<class T>
bool MinHeap<T>::IsFull() const
{
return CurrentSize == MaxSize;
}
template<class T>
void MinHeap<T>::Clear()
{
CurrentSize = 0;
}