首页 > 编程语言 >排序算法 堆排序 HeapSort -- C语言实现

排序算法 堆排序 HeapSort -- C语言实现

时间:2024-08-06 19:06:06浏览次数:17  
标签:parent -- HeapSort 堆排序 int 算法 child ------ 节点

堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:

  1. 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
  2. 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;

堆排序的平均时间复杂度为 Ο(nlogn)。

算法步骤

  1. 创建一个堆 H[0……n-1];
  2. 把堆首(最大值)和堆尾互换;
  3. 把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
  4. 重复步骤 2,直到堆的尺寸为 1。

代码实现

//原理
/*
1、建堆:向下调整算法从下往上建堆
2、选数、向下重新调整堆
*/



/*选择排序*/
static void Swap(int *p1, int *p2)
{
	int tmp = 0;
	tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}



void AdjustDown(int *a, int size, int parent) //小堆
{

	int child = parent * 2 + 1;
	while (child < size)
	{
		if (child + 1 < size &&a[child] < a[child + 1])  //小于选出大的 , 大于选出小的
		{
			child++;
		}
		if (a[child] > a[parent])//小堆大于最小孩子就交换,
		{						 //大堆小于最大孩子就交换
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

void HeapSort(int *a, int size)  //升序建大堆,降序建小堆
{
	/* ---- 向下调整算法建堆  ----*/  //优点,少去最后一层,也是最多的一层,
	//时间复杂度O(n)
	int parent = (size - 1 - 1) / 2;
	while (parent >= 0)
	{
		AdjustDown(a, size, parent);
		parent--;
	}

	/* ---- 选数 ----*/
	//时间复杂度O(n*logN),好像是说n个数都要高度次调整
	int end = size - 1;//不改变原数据
	while (end>0)
	{
		Swap(&a[0], &a[end]);//选数,选完就少一个
		end--;
		AdjustDown(a, end, 0);//
	}

}

时间复杂度分析


/*
向下调整算法建堆时间复杂度计算
假设满二叉树树高度h
各层的节点数为
第一层 2 ^ 0               ------向下调整h-1次
第二层 2 ^ 1               ------向下调整h-2次
第三层 2 ^ 2               ------向下调整h-3次
...    ... 
第h - 1层  2 ^ (h - 2)     ------向下调整1次
第h层  2 ^ (h - 1)

向下调整算法建堆是从最小父亲开始,即第h-1层的最后一个节点 parent = (size-1-1)/2
最坏情况下所有节点需要执行的次数为
f(h) = 2^(h-2)*1 + 2^(h-3)*2 + ... + 2^1*(h-2) + 2^0*(h-1)    错位相减
2*f(h) = 2^(h-1)*1 + 2^(h-2)*2 + ... + 2^2*(h-2) + 2^1*(h-1)
作差、合并得f(h) = 2^h -h-1
其中 满二叉树节点数N = 2^h-1,即h = log(N+1) 代入得
f(N) = N - 1 - log(N+1)  , 舍去logN(数量级)
所以O(n) = n

-------------------------------------------------------------------------------
而向上调整算法建堆时间复杂度比较吃亏,见图
假设满二叉树树高度h
各层的节点数为
第一层 2 ^ 0               
第二层 2 ^ 1               ------向上调整1次
第三层 2 ^ 2               ------向上调整2次
...    ...
第h - 1层  2 ^ (h - 2)     ------向上调整h-2次
第h层  2 ^ (h - 1)         ------向上调整h-1次
计算方法还是错位相减,由图显然可发现向上调整算法执行次数数量级明显提高
不再计算
O(n) = n*logN



总结:向下调整算法跳过最下层最多节点层,且从下层开始节点多执行次数少。快
	向上调整算法从上开始从节点少往节点多执行次数成倍增加,前面的加起来都没最后一层多,慢
*/

标签:parent,--,HeapSort,堆排序,int,算法,child,------,节点
From: https://www.cnblogs.com/DSCL-ing/p/18345467

相关文章

  • 挂载Ceph文件系统以及Ceph存储三副本特性展示
    创建文件系统cephfsvolumecreatecephfs 挂载CephFS的常规先决条件为客户端主机生成最小的conf文件并将其放在标准位置:mkdir-p-m755/etc/cephssh{user}@{mon-host}"sudocephconfiggenerate-minimal-conf"|sudotee/etc/ceph/ceph.conf确保conf具......
  • 数论——绝对素数、素数筛法、埃氏筛法、欧拉筛法、最大公约数
    绝对素数绝对素数是指一个素数在其十进制表示下,无论是从左向右读还是从右向左读,所得到的数仍然是素数。例如,13是一个素数,从右向左读是31,31也是素数,所以13是一个绝对素数。#include<iostream>#include<cmath>usingnamespacestd;boolisPrime(intnum){if(......
  • 关于简单的部分数学函数用python求导的示例
    1.求常数的导数题目代码1.求常数的导数:$f(x)=c$ 运行代码fromsympyimport*x,c=symbols('xc')c.diff(x)结果 2.求幂函数导数:题目代码2.求幂函数导数:$$f(x)=x^\mu$$运行代码fromsympyimport*x,mu=symbols('xmu')(x**mu).diff(x)结果  3.求三角......
  • 什么是大模型?大模型入门指南(非常详细)从入门到精通,看这一篇就够了
    伴随着这段时间,人工智能,AI的热门,“大模型”一词也经常出现在我们的视野中。对于普通人来说,GPT,人工智能,AI,大模型,这些每个字都看得懂但是连起来却觉得理解不完全。今天我们就来讲讲大模型以及GPT。什么是大模型?我们在生活中常常使用过很多模型,比如自制雪糕的雪糕模具,蛋糕店......
  • 我为什么要转行做大模型?
    最近研究了一下大模型相关的内容,决定从互联网的推荐算法转行做大模型推理工程化相关的工作。所以简单说说我在这个决定中的思考过程。1.推荐算法岗的现状我本来是一个在大厂做推荐算法的工程师。收入在行业里面算是中游水平,就这么一直干着似乎也没什么问题。但是互联......
  • 分布式主键 详解
    文章目录雪花算法结合分库分表的问题问题出现原因分析解决思路分布式主键要考虑的问题主键生成策略雪花算法详解时间戳位问题工作进程位问题序列号位问题根据雪花算法扩展基因分片法雪花算法结合分库分表的问题问题出现使用ShardingSphere框架自带的雪花算法生成......
  • 动态贝叶斯网络DBN介绍
    动态贝叶斯网络DBN介绍1.引言2.贝叶斯网络与动态贝叶斯网络2.1贝叶斯网络简介2.2动态贝叶斯网络详细介绍2.3两种网络对比3.搭建动态贝叶斯网络的方法3.1定义网络结构3.2参数学习3.3推理3.4结构学习和参数学习的方法3.4.1结构学习3.4.2参数学习4.总结5.......
  • 一名优秀的AI产品经理成长规划?普通人如何入门?
    最近听到很多人在谈论跳槽面试。其中最多的莫过于在面试中,HR问的:你的职业规划是什么?如果你入职了,在这个岗位想达到怎样的目标?打算如何达到你的目标?你最近3年的职业规划是怎样的?今天跟大家一起探讨探讨:一个产品经理的职业生涯规划,应该是怎么样的?简单来说,产品经理的......
  • 基于CAT计算出的VBM(四)指标与临床量表相关的原理与技术
    前言  前面学习了神经科学中常见的两步分析法:ttest2识别差异:双样本T检验用于在全脑范围内识别疾病组和对照组存在灰质体积差异的脑区团块,定义为ROI。corrROI和临床量表相关分析:进一步,针对疾病组的被试在差异脑区上的灰质体积和临床量表进行相关性分析,针对性的探索该ROI的......
  • MySQL数据库基础1
    sql通用语法SQL语句可以单行或多行书写,以分号结尾。SQL语句可以使用空格/缩进来增强语句的可读性MySQL数据库的SQL语句不区分大小写,关键字建议使用大写注释:单行注释:--注释内容或#注释内容(MySQL特有)多行注释:/*注释内容*SQL分类DDL库操作查询所有数据库sho......