二叉树--堆(下卷)

news2024/9/9 4:44:54

二叉树–堆(下卷)

如果有还没看过上卷的,可以看这篇,链接如下:
http://t.csdnimg.cn/HYhax

向上调整算法

堆的插⼊

将新数据插⼊到数组的尾上,再进⾏向上调整算法,直到满⾜堆。

💡 向上调整算法

• 先将元素插⼊到堆的末尾,即最后⼀个孩⼦之后

• 插⼊之后如果堆的性质遭到破坏,将新插⼊结点顺着其双双亲往上调整到合适位置即可

在这里插入图片描述

代码如下:

//交换两个元素
void Swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}
//堆的向上调整算法
void AdjustUp(HPDataType* arr, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)//此时已经在头结点的位置,不是在根节点,不用等于0
	{
		if (arr[child] < arr[parent])
		{
			Swap( &arr[parent],&arr[child]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

计算向上调整算法建堆时间复杂度

因为堆是完全⼆叉树,⽽满⼆叉树也是完全⼆叉树,此处为了简化使⽤满⼆叉树来证明(时间复杂度本 来看的就是近似值,多⼏个结点不影响最终结果)

在这里插入图片描述

分析:

第1层, 2 0 个结点,需要向上移动0层

第2层, 2 1 个结点,需要向上移动1层

第3层, 2 2 个结点,需要向上移动2层

第4层, 2 3 个结点,需要向上移动3层

第h层, 2 h−1 个结点,需要向上移动h-1层

则需要移动结点总的移动步数为:每层结点个数 * 向上调整次数(第⼀层调整次数为0)

在这里插入图片描述

由此可得:

💡 向上调整算法建堆时间复杂度为: O(n ∗ log n)

节点数量少的调整次数少;节点数量多的调整次数多

向下调整算法

堆的删除

删除堆是删除堆顶的数据,将堆顶的数据根最后⼀个数据⼀换,然后删除数组最后⼀个数据,再进⾏ 向下调整算法。

在这里插入图片描述

向下调整算法有⼀个前提:左右⼦树必须是⼀个堆,才能调整。

💡 向下调整算法

• 将堆顶元素与堆中最后⼀个元素进⾏交换

• 删除堆中最后⼀个元素

• 将堆顶元素向下调整到满⾜堆特性为⽌

在这里插入图片描述

代码如下:

//堆的向下调整
void AdjustDown(HPDataType* arr, int parent, int n)
{
	int child = 2 * parent + 1;//左孩子
	while (child<n)
	{
		if (child + 1 && arr[child] > arr[child + 1])
		{
			child++;//比较孩子大小
		}
		if (arr[parent] > arr[child])
		{
			Swap( &arr[child],&arr[parent]);
		}
		else
		{
			break;
		}
	}
}

在这里插入图片描述

分析:

第1层, 2 0 个结点,需要向下移动h-1层

第2层, 2 1个结点,需要向下移动h-2层

第3层, 2 2 个结点,需要向下移动h-3层

第4层, 2 3 个结点,需要向下移动h-4层

第h-1层, 2 h−2 个结点,需要向下移动1层

则需要移动结点总的移动步数为:每层结点个数 * 向下调整次数

在这里插入图片描述

💡 向下调整算法建堆时间复杂度为: O(n)

节点数量少的调整次数多;节点数量多的调整次数少

堆的应⽤

堆排序

版本⼀:基于已有数组建堆、取堆顶元素完成排序版本

// 1、需要堆的数据结构
// 2、空间复杂度 O(N)
void HeapSort(int* a, int n)
{
HP hp;
for(int i = 0; i < n; i++)
{
HPPush(&hp,a[i]);
}
int i = 0;
while (!HPEmpty(&hp))
{
a[i++] = HPTop(&hp);
HPPop(&hp);
}
HPDestroy(&hp);
}

该版本有⼀个前提,必须提供有现成的数据结构堆

版本⼆:数组建堆,⾸尾交换,交换后的堆尾数据从堆中删掉,将堆顶数据向下调整选出次⼤的数据

void HeapSort(int* arr, int n)
{
	//建堆
	//升序--大堆
	//降序--小堆
	//向上调整算法
	//for (int i = 0; i < n; i++)
	//{
	//	AdjustUp(arr, i);
	//}
	// 堆的向下调整算法
	for (int i=(n - 1 - 1) / 2; i >= 0; i--)//从最后一个节点的父节点开始调整
	{
		AdjustDown(arr, i, n);
	}
	//循环数据,每次减少一个进行对比
	int end = 0;
	while (end > 0)
	{
		Swap(&arr[0], &arr[end]);
		AdjustDown(arr,0 ,end);
		end--;
	}
}

堆排序时间复杂度计算
在这里插入图片描述

分析:

第1层,20 个结点,交换到根结点后,需要向下 移动0层

第2层, 21个结点,交换到根结点后,需要向下 移动1层

第3层,22 个结点,交换到根结点后,需要向下 移动2层

第4层, 23个结点,交换到根结点后,需要向下 移动3层

第h层,2 h-1个结点,交换到根结点后,需要向 下移动h-1层

通过分析发现,堆排序第⼆个循环中的向下调整与建堆中的向上调整算法时间复杂度计算⼀致,此处 不再赘述。因此,堆排序的时间复杂度为 O(n + n ∗ log n) ,即 O(n log n)

💡 堆排序时间复杂度为: O(n log n)

TOP-K问题

思路如下:
在这里插入图片描述

TOP-K问题:即求数据结合中前K个最⼤的元素或者最⼩的元素,⼀般情况下数据量都⽐较⼤。

⽐如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等

对于Top-K问题,能想到的最简单直接的⽅式就是排序,但是:如果数据量⾮常⼤,排序就不太可取了 (可能数据都不能⼀下⼦全部加载到内存中)。最佳的⽅式就是⽤堆来解决,基本思路如下:

1)⽤数据集合中前K个元素来建堆

前k个最⼤的元素,则建⼩堆

前k个最⼩的元素,则建⼤堆

2)⽤剩余的N-K个元素依次与堆顶元素来⽐较,不满⾜则替换堆顶元素

将剩余N-K个元素依次与堆顶元素⽐完之后,堆中剩余的K个元素就是所求的前K个最⼩或者最⼤的元 素

代码如下:

void CreateNDate()
{
// 造数据
int n = 100000;
srand(time(0));
const char* file = "data.txt";
FILE* fin = fopen(file, "w");
if (fin == NULL)
{
perror("fopen error");
return;
}
for (int i = 0; i < n; ++i)
{
int x = (rand()+i) % 1000000;
fprintf(fin, "%d\n", x);
}
fclose(fin);
}
void topk()
{
printf("请输⼊k:>");
int k = 0;
scanf("%d", &k);
const char* file = "data.txt";
FILE* fout = fopen(file, "r");
if (fout == NULL)
{
perror("fopen error");
return;
}
int val = 0;
int* minheap = (int*)malloc(sizeof(int) * k);
if (minheap == NULL)
{
perror("malloc error");
return;
}
for (int i = 0; i < k; i++)
{
fscanf(fout, "%d", &minheap[i]);
}
// 建k个数据的⼩堆
for (int i = (k - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(minheap, k, i);
}
int x = 0;
while (fscanf(fout, "%d", &x) != EOF)
{
// 读取剩余数据,⽐堆顶的值⼤,就替换他进堆
if (x > minheap[0])
{
minheap[0] = x;
AdjustDown(minheap, k, 0);
}
}
for (int i = 0; i < k; i++)
{
printf("%d ", minheap[i]);
}
fclose(fout);
}

哈哈哈相信你在数据结构的学习道路上又进了一步,继续努力加油加油!!!未来的你一定会感谢现在努力的自己。你在三四月做的事情,在七八月会有回报!!
在这里插入图片描述

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

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

相关文章

Monaco 使用 LinkedEditingRangeProvider

Monaco LinkEdit 功能是指同时修改同样的字符串&#xff0c;例如在编辑 Html 时&#xff0c;修改开始标签时会同时修改闭合标签。Monaco 支持自定义需要一起更新的字符串列表。最终效果如下&#xff1a; 首先&#xff0c;通过 registerLinkedEditingRangeProvider 注册 LinkEd…

day17(nginx反向代理)

反向代理 安装nginx 1.26.1 平滑升级 负载均衡 1.nginx 反向代理配置 反向代理&#xff1a;⽤户直接访问反向代理服务器就可以获得⽬标服务器 &#xff08;后端服务器&#xff09;的资源。 反向代理效果&#xff1a;当访问200主机&#xff08;web1&#xff09;&#xff0c;&a…

vite instanceof 失效

背景&#xff1a;给一个巨石单体项目进行标准化模块拆分&#xff0c;封装出来的模块代码用 vite 进行构建&#xff0c;但模块启动后页面上的表现一直和 webpack 那版不一致 一步步 debug 后&#xff0c;发现问题出在下面这个判断条件 const GeneratorFunction function* () …

解决jenkins配置extendreport不展示样式

下载插件&#xff1a;Groovy 、 HTML Publisher plugin 配置&#xff1a; 1&#xff09;Post Steps &#xff1a; 增加 Execute system Groovy script &#xff0c; 内容&#xff1a; System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "&qu…

【React】详解 React Router

文章目录 一、React Router 的基本概念1. 什么是 React Router&#xff1f;2. React Router 的主要特性 二、React Router 的核心组件1. BrowserRouter2. Route3. Link4. Switch 三、React Router 的使用方法1. 安装 React Router2. 定义路由组件3. 配置路由4. 启动应用 四、Re…

再谈istio

微服务之间调用观测&#xff0c; istio的版本是对k8s 版本有要求的&#xff0c;案例中 istioshi 1.15.2 版本的 一、下载 Istio 二、部署 egressgateway 和 ingressgateway 分别控制进出 istio 通过 Envoy proxy&#xff0c;也就是pod加边车的方式来控制用户对svc的访问 这样…

Spring验证码

前言&#xff1a;使用Hutool 1.什么是Hutool&#xff1f; 2.代码复制到test类中 3.代码爆红&#xff0c;说明需要引入依赖 4.根据名取Maven仓库相关依赖 5.在pom.xml文件中进行配置 6.引入成功 7. 运行程序 打开d盘&#xff0c;发现已经生成了验证码的图片&#xff0c;路径在…

Python推荐书单:三本不可错过的经典书籍

强烈推荐这三本书&#xff01;&#xff01; 一、《Python编程从入门到实践》 这本书适合零基础的Python读者&#xff0c;旨在帮助他们快速入门Python编程&#xff0c;并达到初级开发者的水平。书中深入浅出地介绍了Python的基础概念&#xff0c;如变量、循环、函数等&#xff…

智能优化算法(三):遗传算法

文章目录 1.问题描述2.遗传算法2.1.算法概述2.2.编码操作2.3.选择操作2.4.交叉操作2.5.变异操作2.6.算法流程 3.算法实现3.1.MATLAB代码实现3.2.Python代码实现 4.参考文献 1.问题描述 \quad 在利用启发式算法求解问题时&#xff0c;我们常常需要应用遗传算法解决函数最值问题&…

【Golang 面试 - 进阶题】每日 3 题(八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

重塑七人拼团模式:社交电商的裂变新策略

在当今的电商领域&#xff0c;七人拼团模式作为一种创新的商业模式&#xff0c;正以其独特的魅力引领着中小型企业迈向新的增长阶段。这一模式巧妙融合了社交电商的互动性与拼购的趣味性&#xff0c;旨在通过用户间的自然传播&#xff0c;实现市场的快速渗透与品牌影响力的显著…

【赛事推荐】2024中国高校计算机大赛人工智能创意赛

“中国高校计算机大赛”&#xff08;China Collegiate Computing Contest&#xff0c;简称C4&#xff09;是面向全国高校各专业在校学生的科技类竞赛活动&#xff0c;于2016年由教育部高等学校计算机类专业教学指导委员会、教育部高等学校大学软件工程专业教学指导委员会、教育…

NSS [SWPUCTF 2022 新生赛]funny_php

NSS [SWPUCTF 2022 新生赛]funny_php 开题&#xff0c;直接给了源码 <?phpsession_start();highlight_file(__FILE__);if(isset($_GET[num])){if(strlen($_GET[num])<3&&$_GET[num]>999999999){echo ":D";$_SESSION[L1] 1;}else{echo ":C&…

Express基于Node.js基础知识【1】全面总结 推荐收藏

最近在用基于node.js平台的web应用开发做项目&#xff0c;梳理了下关于Express框架的相关知识&#xff0c;方便自己以后查看&#xff0c;希望也能帮助证字啊学习express相关知识的同学&#xff0c;欢迎大家参考&#xff0c;有问题评论区留言&#xff0c;谢谢。 目录 1.安装 …

【人工智能】基础三:深度学习概述、人工神经网络基础

文章目录 一. 深度学习1. 深度学习概念2. 深度学习原理3. 深度学习学习方式4. 深度学习训练方法 二. 人工神经网络基础1. 神经元感知器模型2. 神经网络模型2. 学习方式3. 学习规则3.1. 正向传播求误差3.2. 反向传播求偏导&#xff08;ing&#xff09; 4. 激活函数 一. 深度学习…

【环境搭建问题】linux服务器安装conda并创建虚拟环境

1.检查有没有conda 首先看root文件夹下有没有anaconda或者conda 没有的话就要先下载安装conda&#xff1a; https://repo.anaconda.com/archive/index.html 在这个链接下找自己需要的。服务器一般为linux&#xff0c;所以我这里选择的是&#xff1a; 2.安装conda 下载安装…

阳光混合试验的三个指标

户外干燥气候循环系统&#xff08;仿真模拟空气干燥气侯&#xff09;户外湿冷气侯循环系统&#xff08;仿真模拟寒湿和冰冷晚间气侯&#xff09;室内干燥气候耐久度 阳光模拟温湿度试验箱 主要用于汽车及零部件的曝晒试验、如塑料样板、仪表盘、中控屏、方向盘、保险杠等&…

基于 GADF+Swin-CNN-GAM 的高创新电能扰动信号识别模型!

往期精彩内容&#xff1a; 电能质量扰动信号数据介绍与分类-Python实现-CSDN博客 Python电能质量扰动信号分类(一)基于LSTM模型的一维信号分类-CSDN博客 Python电能质量扰动信号分类(二)基于CNN模型的一维信号分类-CSDN博客 Python电能质量扰动信号分类(三)基于Transformer…

【计算机毕设论文】基于SpringBoot的诗词管理系统

&#x1f497;博主介绍&#xff1a;✌全平台粉丝5W,高级大厂开发程序员&#x1f603;&#xff0c;博客之星、掘金/知乎/华为云/阿里云等平台优质作者。 【源码获取】小伙伴可以关注我 感兴趣的可以先收藏起来&#xff0c;同学门有不懂的毕设选题&#xff0c;项目以及论文编写等…

轻松入门Linux—CentOS,直接拿捏 —/— <1>

一、什么是Linux Linux是一个开源的操作系统&#xff0c;目前是市面上占有率极高的服务器操作系统&#xff0c;目前其分支有很多。是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统 Linux能运行主要的UNIX工具软件、应用程序和网络协议 Linux支持 32…