用堆实现堆排序

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

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

"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;
	}

}
输出结果



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值