基本排序算法(4)——堆排序

       不知不觉,基本排序算法写到4了,应该是比较法排序的最后一篇,选择排序和冒泡排序就不单独总结了。

       堆排序,似乎放在数据结构里面总结更好一些,因为涉及到堆这种数据结构来管理算法执行中的信息,堆排序达到了比较排序的时间下限O(NlogN),空间复杂度只有O(1).

       堆是一个必须掌握的数据结构,一般用数组来表示,表示堆的数组A是一个具有两个属性的对象,length[A]表示数组中的元素个数,即数组的长度,heap-size[A]表示数组中堆的元素个数,亦即,A[heap-size[A]]之后的元素都不属于堆。

       树的根为A[1],给定某个节点的下表i,就能计算出父节点,左孩子,右孩子的下标:

       PARENT(i)=i/2;

       LEFT(i)=2i;

       RIGHT(i)=2i+!;

       如果是大根堆,即对任意元素A[i],有A[PARENT(i)]>=A[i];

       堆有四个基本操作,最重要的是Max_Heapify,用来保持大根堆性质的关键。(小根堆相同)

       Max_Heapify过程如下所述,已知i所指向元素的左右子树均符合大根堆的定义,但A[i]可能小于他的子女,如此图中所示:

       此时应选择其左右子女中最大的一个节点,与i所指向的节点交换,i所指向的节点下移后,递归调用Max_Heapify继续比较其新的子女是否满足大根堆的条件。

       整个过程c++代码如下:(重点

void MaxHeapify(int *a,int index,int heapSize)
{
	int lChildIndex=2*index;
	int rChildIndex=2*index+1;
	int temp,largest=index;
	if(lChildIndex<=heapSize&&a[lChildIndex]>a[largest])
	{
		largest=lChildIndex;
	}
	if(rChildIndex<=heapSize&&a[rChildIndex]>a[largest])
	{
		largest=rChildIndex;
	}
	if(largest!=index)
	{
		temp=a[index];
		a[index]=a[largest];
		a[largest]=temp;
		MaxHeapify(a,largest,heapSize);
	}
}


有了这个函数,堆的其他操作都变得如此简单

在一个数组A[N]上建堆:

void BuildMaxHeap(int *a,int length)
{
	for(int i=length/2;i>=0;i--)
		MaxHeapify(a,i,length);
}


堆排序:

void HeapSort(int *a,int length)
{
	int temp;
	BuildMaxHeap(a,length);
	for(int i=length-1;i>=0;i--)
	{
		temp=a[i];
		a[i]=a[0];
		a[0]=temp;
		length--;
		MaxHeapify(a,0,length);
	}
}


还有一个经常用的操作,即返回根元素A[0],此时A[0]从堆中删去,要求A仍满足大根堆性质,请自行实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值