八大排序之堆排序

堆排序

堆排序基本思想

堆排序是一种使用堆进行排序的排序算法,堆:接近完全二叉树的结构,并且它的每一个子节点都大于(或小于)父节点。每一个子节点都小于父节点的被称为大堆,反之,称作小堆。
在这里插入图片描述

在数组中的存放为:
在这里插入图片描述

堆排序步骤:

  1. 首先将数组中的数据通过向下调整变为大/小顶堆。
  2. 交换堆顶和堆尾数据,将堆尾数据除外后,对堆顶向下调整重新调整为大/小顶堆。
  3. 重复操作2,直到堆中数据只剩一个。

排顺序时,使用大顶堆,这样保证每次交换到堆尾的数据都是当前堆中最大的值。相反如果排逆序,则使用小顶堆,保证每次交换到堆尾的数据都是堆中最小值。

如何构建大/小顶堆:

首先要找到二叉树中的最后一个非叶子节点,即下标为(n-2)/2的节点。之后从它开始逐个向前进行向下调整,直到调整到根节点。
在这里插入图片描述
在这里插入图片描述
代码如下:

int i = 0;
	for (i = (n - 2) / 2; i >= 0; --i)
	{
		HeapAdjustDown(a, n, i);
	}

排序部分:

在这里插入图片描述
代码如下:

int end = n - 1;
	while (end > 0)
	{
		swap(&a[0], &a[end]);
		HeapAdjustDown(a,end,0);
		end--;
	}

完整代码:

void HeapAdjustDown(int* a, int n, int father)
{
	int child = father * 2 + 1;
	while (child < n)
	{
		if (child + 1 < n && a[child + 1]< a[child])
		{
			++child;
		}
		if (a[child] < a[father])
		{
			swap(&a[child], &a[father]);
			father = child;
			child = father * 2 + 1;
		}
		else
		{
			break;
		}
	}

}

void HeapSort(int* a, int n)
{
	int i = 0;
	for (i = (n - 2) / 2; i >= 0; --i)
	{
		HeapAdjustDown(a, n, i);
	}
	int end = n - 1;
	while (end > 0)
	{
		swap(&a[0], &a[end]);
		HeapAdjustDown(a,end,0);
		end--;
	}
}

堆排序效率分析

堆排序是一种不稳定的排序,时间复杂度为O(nlogn)。
堆排序分为两个部分,初始化堆和排序重建堆,初始化堆的时间复杂度为O(N),排序重建的复杂度为O(NlogN),所以整个堆排序过程的时间复杂度为O(nlogn)。
堆排序在初始数据本就是堆的情况下,比较次数减少,不需要构建堆,效率较高。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值