这是之前写过的一篇堆排序的博文之前写的堆排序,下面的这个版本的看起来会比之前写的好理解一些。
用最小堆来进行堆排序,构造好最小堆后,十分简单,构造最小堆的方法和上一篇的最大堆的是类似的,所以这里不再多说,直接上代码
"minheap.h"
#include <iostream>
using namespace std;
template <class T>
class MinHeap
{
private:
T *heap;
int CurSize;
int MaxSize;
public:
MinHeap(int maxsize=10)
{
MaxSize=maxsize;
CurSize=0;
heap=new T[MaxSize+1];
}
~MinHeap()
{
delete[]heap;
}
int Get_Size() const
{
return CurSize;
}
T Get_Min()
{
if(CurSize==0)
{
cout<<"堆为空"<<endl;
return 9999;
}
else
{
return heap[1];
}
}
MinHeap<T> &Insert(const T& x)
{
if(CurSize==MaxSize)
{
cout<<"堆满,"<<x<<" 插入失败"<<endl;
return *this;
}
//为x寻找应插入位置
//i从新的叶子结点开始,沿着树向上
int i=++CurSize;
while(i!=1 && x<heap[i/2])
{
heap[i]=heap[i/2]; //将元素下移
i/=2; //移向父节点
}
heap[i]=x;
cout<<x<<" 插入成功"<<endl;
return *this;
}
MinHeap<T> &DeleteMin(T& x)
{
//将最小元素放入x,并从堆中删除它
if(CurSize==0)
{
x=9999;
return *this;
}
x=heap[1];
//重构堆
heap[0]=heap[CurSize--]; //0号位置存放最后一个元素值,然后将该位置删除
//从根开始,为heap[0]寻找合适位置
int i=1;
int ci=2;
while(ci<=CurSize)
{
//ci是较小的孩子的位置
if(ci<CurSize && heap[ci]>heap[ci+1])
ci++;
//判断是否可以放入heap[i]位置
if(heap[0]<heap[ci])
break;
//不能
heap[i]=heap[ci];
i=ci; // 下移一层
ci*=2;
}
heap[i]=heap[0];
return *this;
}
void Init_heap(T a[],int size,int maxsize)
{
delete[]heap;
heap=new T[maxsize+1];
CurSize=size;
MaxSize=maxsize;
for(int j=1;j<size+1;j++)
heap[j]=a[j];
//产生一个最小堆
for(int i=CurSize/2;i>=1;i--)
{
T y=heap[i]; //子树的根
//寻找放置y的位置
int c=2*i;
while(c<=CurSize)
{
if(c<CurSize && heap[c]>heap[c+1])
c++;
if(y<=heap[c])
break;
heap[c/2]=heap[c];
c*=2;
}
heap[c/2]=y;
}
}
};
测试函数:
#include "minheap.h"
#include <iostream>
using namespace std;
void Heap_Sort(int a[],int n); //堆排序
int main()
{
int a[11]={9999,23,12,-3,-21,1,55,9,-8,10,43};
cout<<"堆排序前,数组a元素顺序如下:"<<endl;
for(int i=1;i<11;i++)
cout<<a[i]<<" ";
cout<<endl;
cout<<endl;
Heap_Sort(a,10);
cout<<"堆排序后,数组a元素顺序为:"<<endl;
for(i=1;i<11;i++)
cout<<a[i]<<" ";
cout<<endl;
cout<<endl;
/*
MinHeap<int> hp;
hp.Init_heap(a,10,15);
int min;
cout<<"目前堆中最小值为:"<<hp.Get_Min()<<endl;
hp.DeleteMin(min);
cout<<"删除的堆中最小的元素为:"<<min<<endl;
cout<<"删除后,现在堆中最小的元素为:"<<hp.Get_Min()<<endl;
cout<<"现在堆的大小为:"<<hp.Get_Size()<<endl;
cout<<"向堆中插入新元素"<<endl;
hp.Insert(22);
hp.Insert(45);
hp.Insert(214);
hp.Insert(16);
hp.Insert(21);
hp.Insert(121);
hp.Insert(111);
cout<<"插入后现在堆的大小为:"<<hp.Get_Size()<<endl;
cout<<"现在由小到大输出堆中元素"<<endl;
do
{
hp.DeleteMin(min);
if(min== 9999)
break;
cout<<min<<" ";
}while(1);
*/
return 0;
}
void Heap_Sort(int a[],int n)
{
MinHeap<int> hp;
hp.Init_heap(a,n,n);
int min;
for(int i=1;i<=n;i++)
{
hp.DeleteMin(min);
a[i]=min;
}
}
输出结果