前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【数据结构】学了数据结构还不会堆排序?--堆排序超详解

【数据结构】学了数据结构还不会堆排序?--堆排序超详解

作者头像
用户9645905
发布于 2022-11-30 04:40:51
发布于 2022-11-30 04:40:51
32200
代码可运行
举报
文章被收录于专栏:Linux学习~Linux学习~
运行总次数:0
代码可运行

目录

前言

背景

排序策略

排序原则

如何建小堆数组

建堆策略1:向上调整

建堆策略2:向下调整

建成小堆之后

测试

具体堆源码


前言


数据结构中我们学了堆的性质及其实现,而这里我们将讲解用堆来实现排序

背景


对给定数组进行堆排序,排成降序

排序策略


排序原则

如果是排升序那么则先将给定数组建立大堆 如果是排降序那么则先将给定数组建立小堆

注:这里排成降序,我们数组建立成一个数组小堆,对于大堆稍作修改就行了

如何建小堆数组

  • 根位置和左右子位置下标关系:

leftchild=root*2+1; rightchild=root*2+2; (leftchild(rightchild)-1)/2=root;

我们依据下标关系,可以找到对应的根位置或者子位置并操作数据建立成堆

建堆策略1:向上调整

  1. 对每个数据进行向上调整直到符合小堆
  2. 当前位置数据和根位置数据比较,如果不符合小堆则交换,直到向上调整到符合小堆
  3. 这里我们可以从第二个数据开始调整,也可以从最后一个数据开始调整
  • 图示过程:从尾部数据往前开始向上调整

建堆策略2:向下调整

  1. 对每个位置数据的根位置数据进行向下调整
  2. 根位置和数据较小的子位置比较,不符合大堆则交换,直到符合
  3. 然而对数据使用向下调整的前提是,根的左右子堆都符合大堆
  4. 所以我们从最后一个数据的根位置开始进行调整,直到堆顶数据调整完毕
  • 图示过程:

建成小堆之后

  1. 我们都知道小堆堆顶的数据永远是当前堆中数据最小的
  2. 我们让堆顶的数据与堆尾数据进行交换(最小的数就排到了最后)
  3. 交换后将除现堆尾的数据看成一个堆
  4. 对交换后的堆顶数据进行向下调整(调整后又成小堆)
  5. 调整后的堆顶数据是当前堆中(包括排除在外的堆尾的最小数)次小的数
  6. 让该堆顶数据与堆倒数第二个数据交换
  7. 以此循环直到交换到堆的正数第二个数据,这个数组降序也就排序好了
  • 过程示图:
  • 参考代码:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//数据调整
void AdjustDown(HPDataType* a, int size, int parent)
{
	int child = parent * 2 + 1;
	while (child<size)
	{		
		//找到数据小的儿子
		if (child + 1 < size && a[child + 1] < a[child])
		{
			child++;
		}
		
		//将父节点与小子节点交换
		if (a[child] < a[parent])
		{
			Swap(&a[child], &a[parent]);//交换数据
			parent = child;//调整下标位置
			child = parent * 2 + 1;
		}
		else
		{
			break;//结束调整
		}
	}
}

// 对数组进行堆排序
void HeapSort(int* a, int n)
{
	//排降序,建立小堆(小堆堆顶数据一定是最小的)
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)//建堆:从最后一个数据的父节点进行向下调整一直到最开始数据
	{
		AdjustDown(a, n,i);
	}
	//将堆顶数据放与末尾数据交换,再将除最小数据外的数组看成堆
	//对当前顶数据调整,调整后当前堆的最小数据处在堆顶位置
	//以此循环,每次最小的数据都放在当前堆的最后面,最终也就成了降序
	for (int end = n - 1; end >= 0; end--)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
	}
}

测试


  • 测试代码:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main()
{
	int a[] = { 70, 56, 30, 25, 15, 10, 75, 33, 50, 69 };
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	HeapSort(a, sizeof(a) / sizeof(a[0]));

	for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	return 0;
}
  • 测试结果: 

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-11-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【数据结构】堆排序与TOP-K问题
为了我只有由后往前向下调整就可以了,第一次要传的参数就是最后一个节点的父节点。然后依次传入前面是位置就可以了。
Yui_
2024/10/16
720
【数据结构】堆排序与TOP-K问题
堆的实现与堆排序
本篇旨在介绍二叉树中特殊结构堆, 以及堆的实现与应用 更多文章 博客主页: 酷酷学!!! 点击关注 一起加油~
用户11317877
2024/10/16
910
堆的实现与堆排序
【数据结构初阶】二叉树--堆(顺序结构实现)
一般堆使用顺序结构的数组来存储数据,堆是一种特殊的二叉树,分为大根堆(大堆)和小根堆(小堆),具有二叉树的特性的同时,还具备其他的特性。
云边有个稻草人
2024/10/21
1310
【数据结构初阶】二叉树--堆(顺序结构实现)
数据结构----堆 和 堆排序 代码
用户11039529
2024/04/15
770
数据结构——堆的应用 堆排序详解
只需要从第二个数8开始每次读取一个数据都向上调整为堆,那么读完整个数组就可以得到一个堆啦~🥰🥰
大耳朵土土垚
2024/03/13
980
数据结构——堆的应用 堆排序详解
数据结构之堆排序
数组建堆,首尾交换,交换后的堆尾数据从堆中删掉,将堆顶数据向下调整选出次大的数据。
egoist祈
2025/01/23
560
数据结构之堆排序
【数据结构初阶第十五节】堆的应用(堆排序 + Top-K问题)
对于本节我们要提前掌握前一节课堆的相关实现才能学好本次的知识,一定要多画图多敲代码看看实现的效果是啥(Crazy!)开始吧!
云边有个稻草人
2025/02/23
810
【数据结构初阶第十五节】堆的应用(堆排序 + Top-K问题)
[数据结构]——二叉树——堆排序
现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。
小李很执着
2024/06/15
870
[数据结构]——二叉树——堆排序
手撕排序之堆排序
数组表示意味着我们就是以数组为结构进行访问,但我们可以通过父子结点的下标关系将其看成树。
用户11316056
2024/10/16
1270
手撕排序之堆排序
【数据结构:排序算法】堆排序(图文详解)
向下调整算法调整该节点的前提是该节点以上的树已经是堆(大堆或者小堆),但是开始的时候,树里面的元素是随便放置的,但是可以把根元素以上看成一个堆,然后向上调整从2*0+1(第二层左边的元素)的位置开始就可以了。
用户11396661
2024/12/09
1970
【数据结构:排序算法】堆排序(图文详解)
数据结构·二叉树(2)
前言:前面介绍了树以及二叉树及其二叉树的存储方式,本文就介绍基于二叉树模式下的一种结构——堆。
_lazy
2024/10/16
900
数据结构·二叉树(2)
【数据结构】堆的概念、结构、模拟实现以及应用
2)堆又分为大堆和小堆,大堆就是树里面任何一个父节点都大于子节点,所以根节点是最大值;小堆就是树里面任何一个父节点都小于子节点,所以根节点也是最小值。
羚羊角
2024/12/29
5320
【数据结构】堆的概念、结构、模拟实现以及应用
【数据结构】堆与堆排序
普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆 ( 一种二叉树 ) 使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统 虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。
用户11290673
2024/09/25
1050
【数据结构】堆与堆排序
【初阶数据结构】森林里的树影 “堆” 光:堆
) i = 0,1,2…,则称为小堆(或大堆)。将根结点最大的堆叫做最大堆或大根堆,根结点最小的堆叫做最小堆或小根堆
DARLING Zero two
2025/02/22
790
【初阶数据结构】森林里的树影 “堆” 光:堆
堆与堆排序操作详解
堆(Heap)是计算机科学中一类特殊的数据结构,是最高效的优先级队列。堆通常是一个可以被看作一棵完全二叉树的数组对象。
用户11029129
2024/06/04
1460
堆与堆排序操作详解
【数据结构与算法】堆的应用:堆排序和topk问题
aosei
2024/01/23
1160
【数据结构与算法】堆的应用:堆排序和topk问题
【初阶数据结构】堆排序和TopK问题
那么我们可以把14默认为是一个符合前提的堆,然后从12往后不断向数组中插入元素,并不断向上调整,直至把整个数组元素全部插完,即完成堆的建立.
MicroFrank
2023/01/16
6400
【数据结构】树和二叉树——Lesson1
树是一种非线性的数据结构,它是由n(n>=0)个有限节点组成的一个具有层次关系的集合。它包含一个根节点以及若干子节点,子节点又可以有自己的子节点,以此类推。
_小羊_
2024/10/16
1240
【数据结构】树和二叉树——Lesson1
数据结构——堆
调整算法用于堆的插入和删除后恢复堆的属性,但是用调整算法的前提是堆原本是有序的(大根堆或者小根堆)
HZzzzzLu
2024/11/26
1350
数据结构——堆
【数据结构与算法】堆排序算法原理与实现:基于堆实现的高效排序算法
综上,堆排序的总时间复杂度为O(n) + O(n *log n) = O(n *log n)。
倔强的石头
2024/12/06
1660
【数据结构与算法】堆排序算法原理与实现:基于堆实现的高效排序算法
相关推荐
【数据结构】堆排序与TOP-K问题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验