用堆实现堆排序

这是之前写过的一篇堆排序的博文之前写的堆排序,下面的这个版本的看起来会比之前写的好理解一些。

用最小堆来进行堆排序,构造好最小堆后,十分简单,构造最小堆的方法和上一篇的最大堆的是类似的,所以这里不再多说,直接上代码

"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; } } 输出结果



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值