堆排序

0)引论

这里我们介绍一下堆排序。堆是一种优先队列,它的性质很简单:树的最小值在根节点上,对于子树依旧成立。因此堆排序的思想也就明确了:把数据以堆的方式存储,然后依次输出根节点。这样就可以把数据按照从小到大的顺序排列出来了。如果需要从大到小排列,则只需要在构建堆的时候,使树的根节点为最大值就可以了。

由堆的性质我们可以得出,堆排序的时间复杂度为O(NlogN)。

1)堆排序

由引论知道,我们只需要构建一个堆,然后依次输出根节点就好了,那么在这里还有什么可说的呢?

如果按照上面的思想,那么我们首先要建立一个堆,那么就需要一些额外的存储空间来存储这些输出的最小值,这样会增加算法的空间复杂度,因此这里介绍一种巧妙的算法来规避这一问题。

当我们对一个堆进行输出最小操作的时候,其实用于存放堆的数组就会空出一个空间,因此我们可以利用这个空间,把输出的排序好的数据一次存放在空出的空间中,如下如所示。

如果是按照从大到小排序的话,那么我们应该构建一个根节点为最大值的堆。


代码实现:

# define LeftChild(i) (2*(i)+1)

void PercDown(ElementType A[],int i,int N)
{
	int Child;
	ElementType Tmp;
	for(Tmp = A[i];LeftChild(i)<N;i=Child)
	{
		Child = LeftChild(i);
		if(Child!=N-1&&A[Child+1]>A[Child])
			Child++;
		if(Tmp<A[Child])
			A[i] = A[Child];
		else
			break;
	}
	A[i] = Tmp;
}
void HeapSort(ElementType A[],int N)
{
	int i;
	for(i=N/2;i>=0;i--)
		PercDown(A,i,N);  //Build Heap
	for(i=N-1;i>0;i--)
	{
		Swap(&A[0],&A[i]);//swap the max-data to the last
		PercDown(A,0,i); //Build Heap for the remine data
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值