堆的应用---堆排序

引言:

一个堆的首元素往往是最大值或者最小值,因此我们可以利用这一特性实现对一组数进行排序。
须注意的是:大堆可以实现一组数的升序排列,小堆则用来实现一组数的降序排列。

实现思路:

当我们有一个堆后(这里用小堆为例):
我们可将首元素(这里即最小的元素)与最后一个元素交换并让堆的大小减一。(因为我们这里已经把堆中最小的数放在了最后的位置,我们剩下要做的便是对其余的元素排序)。
因为父节点的两棵子树任然为小堆,因此对根节点进行向下调整(用向下调整算法),得到一个小堆,第二小的元素便又到了堆顶。
往复上面的操作,我们便对一组数进行了降序排列。

代码实现

向下调整算法:(时间复杂度 :log N)
前提:根节点(这里指函数传参接收的节点)的两棵子树都为小堆(或大堆)
功能:将根节点变为堆顶(即根节点值为最大值或者最小值)

//用于交换子节点和父节点的值
void Swap(int* a, int*b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

//向下调整算法
void AdjustDown(int* array, int numsSize, int root)
{
	int father = root ;
	int child = father * 2 + 1;

	while (child < numsSize)
	{
		//建小堆
		if (child + 1 < numsSize && array[child +1] < array[child ])
		{
			child = child + 1;
		}

		//迭代,让父节点和子节点往树的下层走
		if (array[child] < array[father])
		{
			Swap(&array[child] , &array[father]);

			father = child;
			child = father * 2 + 1;
		}
		else
		{
			//说明堆已经构建好了
			break;
		}

	}
}

堆排序:先构造一个堆,再对该堆进行排序

//堆排序---升序建大堆,降序建小堆
void HeapSort(int* array, int numsSize)
{
	int i = numsSize - 1;

	//构造一个堆
	for ( i; i >= 0; i--)
	{
		AdjustDown(array ,numsSize ,i);
	}

	int total = numsSize - 1;
	for (total; total > 0; --total )
	{
		Swap(&array[0], &array[total]) ; //将首元素(这里即最小的元素)与最后一个元素交换
										 //并让堆的大小减一。因为父节点的两棵子树任然为小堆,因此
										 //对根节点向下调整,得到一个小堆,第二小的元素又到了堆顶
		AdjustDown(array, total, 0); 
	}

}

至此整篇博客已分享完,因编者水平有限,若文章有错误或讲的不清楚的地方,恳请各位大佬评论区留言指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值