堆的向下调整算法,堆排,TopK问题

news2024/10/6 8:22:26

文章目录

  • 堆的向下调整算法
  • 堆的删除:
  • 堆排序
  • 向上调整建堆的时间复杂度
  • 向下调整建堆的时间复杂度为:
  • TopK问题

堆的向下调整算法

我们在这里都已小堆为例:

在这里我们有一个数组
int array[] = {27,15,19,18,28,34,65,49,25,37};
我们通过把根节点向下调整,使数组在逻辑上变成一个小堆。
还未调整前的数组形成的完全二叉树:
在这里插入图片描述
注意向下调整有一个前提:根的左右子树是一个小堆,否则向下调整算法就没有意义了。
在这里插入图片描述
向下调整的过程:
在这里插入图片描述
具体的实现代码:

void AdjustDown(HPDataType* a, int n, int parent)
{
	assert(a);
	//建立小堆,我们假设左孩子是最小的
	int child = parent * 2 + 1; //算出左孩子的下标
	while (child < n) //这里判断条件是,孩子的下标大于等于size就停止循环
	{
		if (child+1<n&&a[child] > a[child + 1])  //child + 1 为右孩子,左孩子大于右孩子,那么右孩子是最小的
		{
			child++;
		}
		//程序走到这一步,就计算哪一个孩子是最小的了
		if (a[child] < a[parent])
		{
			//交换双亲和孩子节点
			Swap(&a[child], &a[parent]);
			//把孩子给双亲,再根据双亲算出下一层的孩子
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break; //调整的途中已经是一个小堆了,就break 意思就是 a[child] > a[parent] 相对于小堆。
			//没有左孩子一定没有右孩子,因为堆是一颗完全二叉树
		}
	}
}

堆的删除:

先把堆顶元素和最后一个元素交换,执行向下调整算法,把除了最后一个元素的数组调整为小堆。
在这里插入图片描述

void HeapPop(HP* php)
{
	assert(php);
	//堆为空时不能在进行删除
	assert(!HeapEmpty(php));
	//删除的思路
	//首先交换堆顶和堆底的数据,然后size--,执行向下调整的算法。
	Swap(&php->a[0], &php->a[php->size - 1]);
	php->size--;
	//执行向下调整算法
	AdjustDown(php->a, php->size, 0);
}

堆排序

思路:把一个数组利用向下调整算法调整为一个堆,先交换堆顶和最后一个元素。这样做的目的是将最小的交换到最后面。执行向下调整算法,把[0,end-1]区间内的元素向下调整为小堆,再重复以上步骤,就可以选出次小的,更小的。我们就完成了排序。
堆排序过程
在这里插入图片描述

结束条件为end > 0。
向下调整建堆时,要从第一个非叶子节点执行向下调整算法。
代码如下:

void HeapSort(HPDataType* a,int n)
{
	//首先执行向上调整算法把一个数组调整为堆
	/*for (int i = 1; i < n; i++)
	{
		AdjustUp(a, i);
	}*/
	//向下调整建堆
	//从第一个不是叶子节点的节点开始向下调整建堆
	for (int i = (n - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, n, i);
	}
	//交换第一个和最后一个数据
	int end = n - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		//不把最后一个数据看成堆里面的数据,执行向下调整算法,选数据,再和最后一个数据交换
		AdjustDown(a, end, 0);
		end--;
	}
}
//时间复杂度为O(nlog(n))

向上调整建堆的时间复杂度

向上调整建堆是一个多乘多的问题。我们看如下的分析:

第一层:1个节点 需要向上移动0次
第二层:2个节点 需要向上移动1次
第三层:4个节点 需要向上移动2次
第四层:8个节点 需要向上移动3次
第 i 层: 2 ( i − 1 ) 2^(i-1) 2(i1)个节点 需要向上移动层数-1次
把上面的节点数和移动次数相乘,利用错位相减法可求得向上调整算法的时间复杂度为:
T(n)=O(logN)
建堆的时间复杂度为:O(nlogN)

向下调整建堆的时间复杂度为:

我们计算建堆过程中总共交换的次数:
在这里插入图片描述

这里是引用

TopK问题

概念:TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。
比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。

思路:利用前k个数据建立小堆,用堆顶元素依次和剩余的n-k个数据比较,比堆顶元素小的就入堆。直至比较完毕,这样的算法大大节省了内存空间的开辟大小。
下面是代码:

void create()
{
	//生成随机数
	srand(time(0));
	int n = 10000;
	//把随机数生成到文件中
	FILE* pin = fopen("1.txt", "w");
	if (pin == NULL)
	{
		perror("fopen failed!\n");
		return;
	}
	//生成n个随机数写入文件中:
	for (int i = 0; i < n; i++)
	{
		int n = rand() % 100000;
		fprintf(pin, "%d\n", n);
	}
	fclose(pin);
}
void PrintTopK(int k)
{
	//打开文件
	FILE* pout = fopen("1.txt", "r");
	if (pout == NULL)
	{
		perror("fopen failed!\n");
		return;
	}
	//把前k个数据读入数组中
	int* arr = (int*)malloc(sizeof(int) * k);
	if (arr == NULL)
	{
		perror("malloc failed!\n");
		return;
	}
	for (int i = 0; i < k; i++)
	{
		fscanf(pout, "%d", &arr[i]);
	}
	//向下调整建立小堆
	for (int i = (k - 1 - 1) / 2; i > 0; i--)
	{
		AdjustDown(arr, k, i);
	}
	//再让剩余的n-k个数据和堆顶元素比较。
	//堆顶元素小于它让它进堆
	int val = 0;
	while (!feof(pout))
	{
		fscanf(pout, "%d", &val);
		if (arr[0] < val)
		{
			arr[0] = val;
			AdjustDown(arr, k, 0);
		}
	}
	//打印数据
	for (int i = 0; i < k; i++)
	{
		printf("%d ", arr[i]);
	}
}

好的我们下一篇再见!

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

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

相关文章

Oracle VM VirtualBox添加磁盘

文章目录 1、Oracle VM VirtualBox添加磁盘 1、Oracle VM VirtualBox添加磁盘 1.关闭正在启动的Oracle VM VirtualBox 2、选择存储 3、点击最右边 4、选择创建 直接下一步&#xff1a; 直接下一步&#xff1a; 调整需要的大小–创建即可: 此时此刻磁盘加载成功&#xff0…

【综合企业管理平台】网络杂谈(10)之什么是Unicenter TNG?

涉及知识点 什么是 Unicenter TNG&#xff0c;Unicenter TNG的基本管理功能&#xff0c;Unicenter TNG Discovery &#xff0c;深入了解Unicenter TNG技术&#xff0c;综合企业管理平台 Unicenter TNG 。 原创于&#xff1a;CSDN博主-《拄杖盲学轻声码》&#xff0c;更多内容可…

8.串行通信

1.通信接口相关知识&#xff1a; &#xff08;1&#xff09;处理器与外界设备通信的两种方式&#xff1a; 1&#xff09;并行通信&#xff1a; 传输原理&#xff1a;数据各个位同时传输&#xff1b; 优点&#xff1a;速度快&#xff1b; 缺点&#xff1a;占用引脚资源多&…

vue+leaflet笔记之地图网格

vueleaflet笔记之地图网格 本文介绍了Web端使用Leaflet开发库显示地图经纬网和标准图幅网格的方法 (底图来源:天地图)&#xff0c; 地图格网是由间隔均匀的横向线和纵向线组成的网络&#xff0c;用于在地图上识别各个位置。 经纬网通过在地图上描绘纬度和经度格网&#xff0c;…

40.Docker

目录 一、Docker。 &#xff08;1&#xff09;认识Docker。 &#xff08;1.1&#xff09;什么是Docker。 &#xff08;1.2&#xff09;Docker和虚拟机的区别。 &#xff08;2&#xff09;镜像、容器、DockerHub、Docker架构。 &#xff08;3&#xff09;安装Docker&#…

VS+QT+VTK三维曲面网格点选切割

程序示例精选 VSQTVTK三维曲面网格点选切割 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<VSQTVTK三维曲面网格点选切割>>编写代码&#xff0c;代码整洁&#xff0c;规则&…

DAMA学习笔记1:概念模型-逻辑模型篇

A实体的某个字段指向 B实体的主键, 则称A实体的那个字段为该实体的外键, 一个表里可以有多个外键&#xff0c;也可以没有外键&#xff1b; 被指向的实体称为主实体(主表)&#xff0c;也叫父实体(父表)&#xff0c;负责指向的实体称为从实体(从表)&#xff0c;也叫子实体(子表)…

记录好项目D18

记录好项目 你好呀&#xff0c;这里是我专门记录一下从某些地方收集起来的项目&#xff0c;对项目修改&#xff0c;进行添砖加瓦&#xff0c;变成自己的闪亮项目。修修补补也可以成为毕设哦 本次的项目是个网上商城 一、系统介绍 前台商城系统&#xff1a;包含首页登录、商…

动态规划——下降路径最小和

题目链接 leetcode在线oj题——下降路径最小和 题目描述 给你一个 n x n 的 方形 整数数组 matrix &#xff0c;请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始&#xff0c;并从每一行中选择一个元素。在下一行选择的元素和当前…

mmpose冻结参数训练,如何添加find_unused_parameters参数

mmpose冻结参数训练&#xff0c;如何添加find_unused_parameters参数 在backbone下方添加 frozen_stages7即可冻结前7层的参数。要注意对于多卡训练来说还需要添加 find_unused_parameters True。看图片中代码的位置。

回忆雅礼朱哥二三事

少年时代的记忆是最模糊的&#xff0c;却也是最深刻的。一些瞬间在大脑里几十年&#xff0c;那一定是你曾经心动和在乎过的感受。年少求学期间&#xff0c;因对数学的痴迷&#xff0c;和数学有关的一切我都记忆犹新&#xff1a;记得一个人趴在地上解题一下午的投入&#xff0c;…

分析各种富文本框的自动填写方法

怎样自动填写表单中的富文本框&#xff1f; 什么是富文本框&#xff1f;富文本框就是在网页上可以输入带格式的文本输入框。在富文本框中&#xff0c;可以设置使用不同的字体、颜色&#xff0c;可以控制段落、边距&#xff0c;还可以插入图片、表情等。是实现在线编辑不可或缺…

c++ word简单的写文本与画表格只支持docx

简单使用的代码如下所示&#xff1a; #include "stdafx.h" #include <windows.h> #include "minidocx.hpp" using namespace docx; using namespace std; std::string GB2312ToUTF8(const std::string& gb2312) { int len MultiByteToWid…

【ESP32C3合宙ESP32C3】:ESP32C3和合宙ESP32C3的环境搭建与离线包安装

项目场景&#xff1a; 最近买了一块合宙ESP32C3的开发板&#xff0c;于是想要开发一下&#xff0c;当然开发最开始少不掉开发环境的搭建&#xff0c;在这个搭建的过程中&#xff0c;遇到了一些问题&#xff0c;解决了&#xff0c;也希望能帮助到大家。 ESP32C3 和 合宙ES…

Spring Boot 中的 Elasticsearch 的数据操作配置

Spring Boot 中的 Elasticsearch 的数据操作配置 Elasticsearch是一个基于Lucene的搜索引擎&#xff0c;可以快速地存储、搜索和分析大量的数据。Spring Boot是一个开发框架&#xff0c;提供了快速构建基于Spring的应用程序的工具和技术。在本文中&#xff0c;我们将讨论如何在…

GBASE南大通用时代亿信共筑商业秘密防护联合解决方案

当前&#xff0c;数字经济因其覆盖面广且渗透力强&#xff0c;与各行业深度融合&#xff0c;正在逐渐引领新经济发展。另一方面&#xff0c;数据安全已上升为国家战略&#xff0c;中央相继出台政策文件&#xff0c;加强数据安全、商业秘密、个人隐私保护&#xff0c;提高网络安…

聚观早报 | 美团收购光年之外;世卫:可乐中甜味剂或致癌

今日要闻&#xff1a;美团以20.65亿人民币收购光年之外&#xff1b;世卫&#xff1a;可乐中甜味剂或致癌&#xff1b;AI公司融13亿美元&#xff0c;仅次于OpenAI&#xff1b;微信支付就校园支付费率过高致歉&#xff1b;B站回应成立交易生态中心 美团以20.65亿人民币收购光年之…

C# Excel 表列序号

171 Excel 表列序号 给你一个字符串 columnTitle &#xff0c;表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。 例如&#xff1a; A -> 1 B -> 2 C -> 3 … Z -> 26 AA -> 27 AB -> 28 … 示例 1: 输入: columnTitle “A” 输出: 1 示例 2: …

11-Vue的diff算法

参考回答&#xff1a;​​​​​​​ 当组件创建和更新时&#xff0c;vue均会执行内部的update函数&#xff0c;该函数使用render函数生成的虚拟dom树&#xff0c;将新旧两树进行对比&#xff0c;找到差异点&#xff0c;最终更新到真实dom对比差异的过程叫diff&#xff0c;vue在…

《移动互联网技术》第五章 界面开发: 掌握Activity的基本概念,Activity的堆栈管理和生命周期

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…