快速学习“堆“排序(C语言数据结构)

news2024/9/22 15:29:10

前言:

        堆的实现其实并不难,难的是要用堆实现排序,也就是堆的运用

        下面需要探究一下堆的排序是怎样的。

        如何利用堆进行升序或者降序的排序。

"堆排序":

   原理:

        例如:此时要将数组里的数组int arr[] = {12,20,26,8,1,2,3}进行升序或者降序排序

第一步:把数放进堆里面,但是究竟是放在大堆还是小堆里面呢?

如果需要升序就需要放进大堆里面!

如果需要降序就需要放进小堆里面!

(原因后续画图讲解)

如何将一个数组直接放在大堆当中呢?

可以直接遍历数组,将数一个一个放入。

代码如下:

typedef int HPDataType;
void AdjustUp(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}
void HeapPush(Heap* hp, HPDataType x)
{
	assert(hp);
	if (hp->_capacity == hp->_size)
	{
		int newcapacity = hp->_capacity == 0 ? 4 : hp->_capacity * 2;
		HPDataType* tmp = (HPDataType*)realloc(hp->_a, newcapacity * sizeof(HPDataType));
		if (tmp == NULL)
		{
			perror("malloc::error");
			exit(-1);
		}
		hp->_capacity = newcapacity;
		hp->_a = tmp;
	}
	hp->_a[hp->_size] = x;
	hp->_size++;
	AdjustUp(hp->_a, hp->_size - 1);
}
void test2()
{
	Heap hp;
	HeapInit(&hp);
	int arr[] = {12,20,26,8,1,2,3};
	int i = 0;
	int size = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < size; i++)
	{
		HeapPush(&hp, arr[i]);
	}

}

此时就直接形成了”大堆“。

第二步:每次需要交换首和尾

              交换之后将除了新的尾的数之外的数进行向下调整

              也就是将除了26以外的数进行向下调整:

向下调整:

第三步:以此类推,直到遍历到第一个数为止。

大家可以亲自动手画一画,很有助于理解。

我把这个方法称之为“沉淀法”!

此时最后就是一个升序的树,可以直接按照顺序打印出来。

代码如下:

void AdjustUp(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}
void HeapPush(Heap* hp, HPDataType x)
{
	assert(hp);
	if (hp->_capacity == hp->_size)
	{
		int newcapacity = hp->_capacity == 0 ? 4 : hp->_capacity * 2;
		HPDataType* tmp = (HPDataType*)realloc(hp->_a, newcapacity * sizeof(HPDataType));
		if (tmp == NULL)
		{
			perror("malloc::error");
			exit(-1);
		}
		hp->_capacity = newcapacity;
		hp->_a = tmp;
	}
	hp->_a[hp->_size] = x;
	hp->_size++;
	AdjustUp(hp->_a, hp->_size - 1);
}
void HeapInit(Heap* hp)
{
	assert(hp);
	hp->_a = NULL;
	hp->_capacity = hp->_size = 0;
}
void AdjustDown(HPDataType* a, int size, int parent)
{
	//假设最大的孩子的值是左孩子对应的数值
	int childmax = (parent * 2) + 1;
	while (childmax < size)
	{
		//如果右有孩子并且右孩子的值是大于左孩子将最大的孩子换成右孩子
		if (childmax + 1 < size && a[childmax + 1] > a[childmax])
		{
			childmax = childmax + 1;
		}
		if (a[parent] < a[childmax])
		{
			swap(&a[parent], &a[childmax]);
			parent = childmax;
			childmax = (parent * 2) + 1;
		}
		else
		{
			break;
		}
	}
}
void test2()
{
	Heap hp;
	HeapInit(&hp);
	int arr[] = {12,20,26,8,1,2,3};
	int i = 0;
	int size = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < size; i++)
	{
		HeapPush(&hp, arr[i]);
	}
	for (i = 0; i < size; i++)
	{
		//交换首尾
		swap(&hp._a[0], &hp._a[hp._size - 1 - i]);
		//向下调整
		AdjustDown(hp._a, hp._size-1-i, 0);
	}
	for (i = 0; i < size; i++)
	{
		arr[i] = hp._a[i];
	}
	for (i = 0; i < size; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	//test1();
	test2();
	return 0;
}

"十万个数据"进行堆排序:

        大数据时代,如果有10万个数据要进行排序,该怎么排序。

        究竟是用哪种排序的方式时间复杂度最低呢?

     在这之前需要我们计算一下”堆排序“的时间复杂度!

建堆的时间复杂度:


堆排序的时间复杂度:

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2074862.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

干货实用帖 | PARASOFT与JENKINS 插件集成

&#x1f4d6; 介绍&#xff1a; 本篇介绍如何使用Jenkins上的插件Parasoft Findings&#xff0c;应用到C/Ctest项目中。 ✅ 准备工作&#xff1a; Jenkins项目C/Ctest 10.4以上版本及有效的许可证 视频教学&#xff1a; Parasoft与Jenkins插件集成 安装插件&#xff1a; 首先…

Vue3 获取农历(阴历)日期,并封装日历展示组件

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;我是码喽的自我修养&#xff01;今天给大家分享vue3项目中使用 chinese-lunar-calendar 插件获取农历(阴历)日期&#xff0c;并封装了日历展示组件&#xff01;提供了具体的代码帮助大家深入理解&#xff0c;彻底掌握&#…

【舞动生命,营养护航】亨廷顿舞蹈症患者的维生素补给站

Hey小伙伴们~&#x1f44b; 在这个充满色彩的世界里&#xff0c;每个人都在以自己的方式绽放光彩。但你知道吗&#xff1f;有一群特别的朋友&#xff0c;他们面对着亨廷顿舞蹈症的挑战&#xff0c;却依然以不屈不挠的精神舞动着生命的旋律。&#x1f483;✨ 今天&#xff0c;就…

游戏如何对抗 IL2cppDumper逆向分析

众所周知&#xff0c;Unity引擎中有两种脚本编译器&#xff0c;分别是 Mono 和 IL2CPP 。相较于Mono&#xff0c;IL2CPP 具备执行效率高、跨平台支持等优势&#xff0c;已被大多数游戏采用。 IL2CPP 模式下&#xff0c;可以将游戏 C# 代码转换为 C 代码&#xff0c;然后编译为…

STM32学习记录-06-ADC模数转换器

1 ADC简介 ADC(Analog-Digital Converter)模拟-数字转换器 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁 12位逐次逼近型ADC,1us转换时间 输入电压范围:0~3.3V,转换结果范围:0~4095 18个输入通道,可测量16个外部和…

FPGA在医疗方面的应用

可编程逻辑支持以灵活、低风险的方式成功实施系统设计&#xff0c;同时提供了最佳的成本效率和增值的差异化功能&#xff0c;延长了医疗保健应用的生命周期&#xff0c;包括诊断成像、电子医疗、治疗和生命科学与医院设备。 在医疗方面的应用非常广泛&#xff0c;以下是几个主…

Langchain Memory组件深度剖析:从对话基础到高级链式应用

文章目录 前言一、Langchain memory 记忆1.Memory 组件基本介绍2.Memory 组件的类型1.ChatMessageHistory2.ConversationBufferMemory3.ConversationBufferWindowMemory4.ConversationEntityMemory5.ConversationKGMemory6.ConversationSummaryMemory 二、长时记忆1.简单介绍2.…

Error: Can not import paddle core while this file exists

背景 因为工作需要&#xff0c;原来的项目部署的电脑被征用&#xff0c;重新换了一个新电脑&#xff0c;重装了系统&#xff0c;今天在给一个使用ocr的项目进行环境配置的时候发现&#xff0c;无论安装哪个版本的paddlepaddle&#xff0c;总是可以安装成功&#xff0c;但是导入…

Android CCodec Codec2 (四)C2Param - Ⅱ

这一篇内容我们来解答复杂参数定义过程中提出的疑问&#xff0c;本文有大量的模板和宏展开&#xff0c;请耐心阅读。 1、不含灵活数组的复杂结构体定义 DEFINE_AND_DESCRIBE_C2STRUCT和C2FIELD是不能分开的&#xff0c;使用时必须要按顺序依次调用这两个宏定义。宏定义比较复杂…

【机器学习-监督学习】神经网络与多层感知机

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科&#xff0c;通过算法和模型让计算机从数据中学习&#xff0c;进行模型训练和优化&#xff0c;做出预测、分类和决策支持。Python成为机器学习的首选语言&#xff0c;…

java-Mybaits框架01

1.框架概念 在基础语言之上&#xff0c;对各种基础功能进行封装&#xff0c;方便开发者&#xff0c;提高开发效率&#xff1b; java后端框架 mybaits&#xff1a;对jdbc进行封装 Spring&#xff1a;对整个java后端架构进行管理。 SpringWeb&#xff1a;对web&#xff08;S…

vxe-grid 利用dayjs提供的方法来格式化, 计算二个日期之间的年数/年龄

1、安装dayjs pnpm add dayjs yarn add dayjs npm install dayjs 2、导入 import dayjs from dayjs; 3、vxe-grid列&#xff1a; export const UserColumns: VxeGridPropTypes.Columns [ ... {title: 年龄,width: 70,field: old,showOverflow: tooltip,align: center,sortabl…

android studio 设置gradle jdk

1. 左上角点击file 2. 按照如下点击&#xff1a; 3. 即可修改gradle jdk

EasyExcel文件导出简洁版

1. EasyExcel简介 EasyExcel是一个基于Java的简单、快速、lightweight的Excel处理库。它的主要特点包括: 轻量级设计: EasyExcel的jar包大小仅约1MB,相比较其他Excel处理库如Apache POI来说更加轻量。 采用内存友好的流式读写模式,无需一次性加载整个Excel文件到内存,大大减少…

Linux的CPU调度优化详解

一、引言 随着计算机硬件技术的不断发展和进步&#xff0c;现代服务器和工作站通常都配备了多核CPU&#xff0c;为了充分发挥多核处理器的性能优势&#xff0c;Linux系统提供了多种CPU调度器以及相关的参数设置&#xff0c;以便进行CPU调度优化&#xff0c;提高系统的整体性能…

AI 音频/文本对话机器人:Whisper+Edge TTS+OpenAI API构建语音与文本交互系统(简易版)

文章目录 前言思路&#xff1a;环境配置代码1. 加载Whisper模型2. 使用Whisper语音转文本3. 使用OpenAI API生成文本进行智能问答4. 实现文本转语音功能5. 合并音频文件6. 构建Gradio界面注意 总结 前言 在本篇博客中&#xff0c;我将分享如何利用Whisper模型进行语音转文本&a…

GFS系统架构

GFS系统架构 针对上述观察&#xff0c;我们发现它们与早期文件系统的设计假设存在显著差异。为此&#xff0c;我们采取了以下解决方案&#xff1a; 组件故障&#xff1a;我们接受故障为常态&#xff0c;系统设计以自我监控和快速恢复为原则&#xff0c;适应低成本硬件环境下的…

基础算法--递推算法[信奥一本通]

本节所讲题源自【信奥一本通】C版&#xff1a;基础算法-第三章-递推算法 相信大家应该都接触过数列的概念。哎哟&#xff0c;一直在跟数组打交道&#xff0c;说数列感觉好陌生&#xff0c;哈哈。数列中的迭代法大家都还记得吗&#xff1a;通过反复应用特定规则&#xff0c;推导…

Linux系统中的Btrfs技术

在Linux操作系统中&#xff0c;文件系统扮演着至关重要的角色&#xff0c;负责管理数据存储、文件访问以及系统的稳定性。其中&#xff0c;Btrfs&#xff08;B-tree file system&#xff09;作为一种先进的文件系统技术&#xff0c;正在逐渐引起广泛关注和应用。本文将深入探讨…

【算法】深入浅出聚类算法:原理、应用与Java实现

一、引言 在数据分析和机器学习中&#xff0c;聚类算法是一种无监督学习技术&#xff0c;用于将数据集中的对象自动划分为多个子集&#xff0c;每个子集称为一个簇。聚类算法在多个领域有着广泛的应用&#xff0c;如图像处理、信息检索、市场细分、生物信息学等。本文将介绍聚…