数据结构|排序算法(三)堆排序

二、堆排序

堆是一种特殊的完全二叉树,分为大根堆和小根堆。

大根堆的每个节点的值都大于或等于其左右子节点的值,小根堆则相反,每个节点的值都小于或等于其左右子节点的值。(大根堆小根堆只看父子关系)

堆排序的基本思想是将待排序的序列构建成一个堆,然后依次取出堆顶元素并调整堆,直到整个序列有序。

1.算法思想

建堆:将给定的数组构建成一个大根堆(或小根堆)。从最后一个非叶子节点开始,依次向上调整每个节点,使其满足堆的性质。

交换元素:将堆顶元素与堆的最后一个元素交换位置,此时堆顶元素是当前堆中的最大(或最小)值,将其取出,放到已排序序列的末尾。

调整堆:交换元素后,堆的性质可能被破坏,需要对剩余的元素重新调整堆,使其再次满足堆的性质。重复步骤 2 和 3,直到堆中只剩下一个元素,此时整个数组已经有序。

1->调整成大根堆

(1)从最后一棵子树开始,从后往前调整

(2)每次调整,从上往下

(3)整体调整成大根堆

具体调整:

定义一个临时变量tmp,把根放到tmp里,找左右孩子的最大值,和tmp比较,如果比tmp大,则放到根的位置,继续递归比较新的左右孩子的最大值

调整顺序:
调整子树:调整完成:

2->根和待排序的最后一个交换

根是最大的,交换后则视作有序

3->再次调整成大根堆

2.代码实现

复制代码
//堆排序
 
void HeapAdjust(int* arr, int start, int end)
{
	int tmp = arr[start];
	for (int i = 2 * start + 1; i <= end;i=2*i+1)//从上往下
	{
		if (i < end && arr[i] < arr[i + 1])//如果有右孩子,且左孩子的值小于右孩子
		{
			i++;
		}//i一定是左右孩子的最大值
		if (arr[i] > tmp)
		{
			arr[start] = arr[i];
			start = i;
		}
		else
		{
			break;
		}
	}
	arr[start] = tmp;
}
 
void HeapSort(int* arr, int len)
{
	//第一次建立大根堆(从后往前,多次调整)//根分别为4 3 2 1的子树
	for (int i = (len-1-1)/2; i >= 0; i--)//i的初值与结点总数有关,i=总结点数len-根-
	{
		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);
	}
	
	return;
}

3.复杂度分析

建立大根堆的时间复杂度:O(n)

每次调整大根堆时间复杂度:O(logn),调整次数n-1次,总时间复杂度O(nlogn)

综合建堆和排序两个阶段,堆排序的时间复杂度为O(n+nlogn),通常简化为O(nlogn)。这是堆排序的平均时间复杂度;

空间复杂度O(1);

不稳定

相关推荐
cxoptics10 分钟前
偏振片(起偏器/检偏器)怎么区分?
java
StevenLdh29 分钟前
第四期 · 云端同步与冲突仲裁:离线可写、多端一致的工程解法
java·微信小程序
Rabitebla30 分钟前
【Linux系统编程】指令(三):创建、删除、复制、移动、看内容
linux·数据结构·c++·算法
事已至此先睡覺吧39 分钟前
第三篇:Java 流程控制详解:条件判断、循环与跳转语句
java·开发语言
毕业设计70341 分钟前
(免费领源码) SpringBoot 游戏交易平台17600-java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
java·spring boot·mysql·决策树·mybatis·idea·推荐算法
一 乐1 小时前
自习室座位预约管理系统|基于springboot + vue自习室座位预约管理系统(源码+数据库+文档)
java·vue.js·spring boot
此时不提桶,更待何时1 小时前
02-02-B-AQS与JUC锁面试与生产事故实战
java
音符犹如代码1 小时前
Kafka 接入 AI 的三条路线:MCP 提案、会话记忆与实时上下文
java·大数据·ai·kafka
vx_BS813301 小时前
【项目编号:project51629】Spring Boot 乡村自来水缴费系统:把抄表、水费生成与在线缴费做成一条数字化闭环
java·spring boot·eclipse·tomcat·maven
qq_269506751 小时前
第29课-Servlet基础
java