堆排序

算法描述

将待排序序列构造成一个大根堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了

  1. 构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。
  2. 将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。

算法排序:

给9 4 7 34 21 33 8 0 67 6排序
在这里插入图片描述
第一次大根堆:
第一次大根堆在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
父 —> 子 n: 2n+1 2n+2
子 —> 父 n: (n-1)/2
第一次大根堆:从最后一颗子树开始,从后往前多次调整
一次堆调整:从上往下调整

时间复杂度

堆排序
时间复杂度:O(nlogn)
空间复杂度:O(1)
不稳定
第一次大根堆:
时间复杂度:O(nlogn)
空间复杂度:O(1)
不稳定
一次堆调整:
时间复杂度:O(logn)
空间复杂度:O(1)

代码实现:

#include <stdio.h>
#include <stdlib.h>
//一次堆调整
void HeapAdjust(int *arr,int start,int end)//O(logn),O(1)
{
	int tmp =	arr[start];
	int i;
	for(i=2*start+1;i<=end;i=2*i+1)
	{
		if(i+1<=end && arr[i]<arr[i+1])//i是左右孩子较大值的下标
			i++;
		if(tmp < arr[i])//arr[i]需要上移
		{
			arr[(i-1)/2] = arr[i];
		}
		else  //找到位置
		{
			break;
		}
	}
	arr[(i-1)/2] = tmp;
}

void HeapSort(int *arr,int len)//O(nlogn),O(1),不稳定
{
	//第一次建大根堆
	for(int i=(len-1-1)/2;i>=0;i--)
	{
		HeapAdjust(arr,i,len-1);
	}

	int tmp;
	for(int i=0;i<len-1;i++)
	{
		tmp = arr[0];
		arr[0] = arr[len-1-i];
		arr[len-1-i] = tmp;
		HeapAdjust(arr,0,len-1-i-1);
	}
}
int main()
{
	int arr[] = {4,9,0,12,34,67,8,91,32,54,66,88,2};
	HeapSort(arr,sizeof(arr)/sizeof(arr[0]));
	Show(arr,sizeof(arr)/sizeof(arr[0]));

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值