【堆排序的思路】
堆排序主要是利用了堆的性质,对于大顶堆:堆中的每个节点的值都不小于它的孩子节点的值,详细可参考我的另一篇博客http://blog.csdn.net/adminabcd/article/details/46880591,那么大顶堆的堆顶元素就是当前堆中所有元素中最大的。
利用这个性质,进行如下操作,则可以得到一个有序序列:
- 将待排序的n个元素一个一个插入堆中,那么此时堆顶元素就是所有元素中最大的
- 将堆顶元素取出,剩下的n-1个元素组成新的堆,新堆的堆顶元素是当前堆中元素中最大的,也就是所有元素中第二大的。
将堆顶元素取出,剩下的n-2个元素组成新的堆,新堆的堆顶元素是当前堆中元素中最大的,也就是所有元素中第三大的。
.
.
.
.直到所有元素取出,此时所有取出元素序列就是一个从大到小的有序序列。
【代码实现】
- 大顶堆的实现
#ifndef maxheap_h
#define maxheap_h
template<class T>
class Maxheap
{
public:
Maxheap(int size);
~Maxheap();
bool Isempty();
void push(T item); //插入操作
void pop(); //删除操作
T top();
private:
T *heap;
int currentSize;
int capacity;
};
//-------构造函数初始化-------
template<class T>
Maxheap<T>::Maxheap(int size)
{
if(size<1)
{
throw"capacity must be >=1";
}
else
{
currentSize=0;
capacity=size;
heap=new T[capacity+1]; //heap[0]不使用
}
}
//-------析构函数释放空间-------
template<class T>
Maxheap<T>::~Maxheap()
{
delete []heap;
}
//--------判断堆是否为空-------
template<class T>
bool Maxheap<T>::Isempty()
{
return currentSize==0;
}
//---------获取最大元素----------
template<class T>
T Maxheap<T>::top()
{
return heap[1];
}
//-------插入操作-----
template<class T>
void Maxheap<T>::push(T item)
{
if(currentSize==capacity)
throw"Maxheap is full";
else
{
currentSize++;
int currentNode=currentSize;// 元素的插入位置初始化为最后
while(currentNode>1&&heap[currentNode/2]<item) //(从下往上)进行调整
{
heap[currentNode]=heap[currentNode/2];
currentNode=currentNode/2;
}
heap[currentNode]=item; //插入元素
}
}
//-----删除操作-------
template<class T>
void Maxheap<T>::pop()
{
if(Isempty())
throw"heap is empty ,cannot delete";
else
{
T last=heap[currentSize]; //将最后一个元素初始化为根
currentSize--;
int currentNode=1;
int child=2;
while(child<=currentSize) //(从上往下)进行调整
{
if(child<currentSize&&heap[child]<heap[child+1])
child++;
if(last>=heap[child])
break;
else
{
heap[currentNode]=heap[child];
currentNode=child;
child=child*2;
}
}
heap[ currentNode]=last;
}
}
#endif
- 堆排序实现
#include"MAXHEAP.h"
#include<iostream>
using namespace std;
int main()
{
Maxheap<int> H(100);
int arr[]={50,15,30,70,6};
for(int i=0;i<5;i++)
{
H.push(arr[i]); //元素进堆
}
for(int i=0;i<5;i++)
{
arr[i]= H.top();
H.pop(); //取出堆顶元素,其余元素组成新的堆
}
cout<<"降序排序:";
for(int i=0;i<5;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
cout<<"升序排序:";
for(int i=4;i>=0;i--)
{
cout<<arr[i]<<" ";
}
cout<<endl;
system("pause");
return 0;
}
【结果】