大根堆小根堆及其应用

大小顶堆/根堆/heap 小顶堆就是小根堆,是small heap的翻译。 阅读详情

堆的概念

堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:
Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]或者Key[i]>=Key[2i+1]&&key>=key[2i+2]
即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。
堆分为大顶堆和小顶堆,满足Key[i]>=Key[2i+1]&&key>=key[2i+2]称为大顶堆,满足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]称为小顶堆。由上述性质可知大顶堆的堆顶的关键字肯定是所有关键字中最大的,小顶堆的堆顶的关键字是所有关键字中最小的。

其中,大根堆和小根堆在海量数据的top N问题中,有着很好的时间复杂度。

首先,先给出一个交换两个变量数值的函数。

void Swap(uint32_t* array, uint32_t i, uint32_t j)
{
	assert(array);
	uint32_t tmp = 0;
	tmp = array[j];
	array[j] = array[i];
	array[i] = tmp;
}

头文件包含

#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>

大根堆实现

/*大根堆调整*/
void MaxHeapify(uint32_t* array, uint32_t heapSize, uint32_t currentNode)
{
	uint32_t leftChild = 0, rightChild = 0,  largest = 0;
	leftChild = 2*currentNode + 1;
	rightChild = 2*currentNode + 2;
	if(leftChild < heapSize && array[leftChild] > array[currentNode])
		largest = leftChild;
	else
		largest = currentNode;
	if(rightChild < heapSize && array[rightChild] > array[largest])
		largest = rightChild;
	if(largest != currentNode)
	{
		Swap(array, largest, currentNode);
		MaxHeapify(array, heapSize, largest);
	}
}

/*构建大根堆*/
void MaxHeapCreat(uint32_t* array, uint32_t heapSize)
{
	int i = 0;
	for(i = heapSize/2; i >= 0; i--)
	{
		MaxHeapify(array, heapSize, i);
	}
}

小根堆实现

/*小根堆调整*/
void MinHeapify(uint32_t* array, uint32_t heapSize, uint32_t currentNode)
{
	uint32_t leftChild = 0, rightChild = 0,  minimum = 0;
	leftChild = 2*currentNode + 1;
	rightChild = 2*currentNode + 2;
	if(leftChild < heapSize && array[leftChild] < array[currentNode])
		minimum = leftChild;
	else
		minimum = currentNode;
	if(rightChild < heapSize && array[rightChild] < array[minimum])
		minimum = rightChild;
	if(minimum != currentNode)
	{
		Swap(array, minimum, currentNode);
		MinHeapify(array, heapSize, minimum);
	}
}
/*构建小根堆*/
void MinHeapCreat(uint32_t* array, uint32_t heapSize)
{
	int i = 0;
	for(i = heapSize/2; i >= 0; i--)
	{
		MinHeapify(array, heapSize, i);
	}
}

 

top N问题

利用小根堆解决获取大量数据中最大的N个值,先构建一个拥有N个元素的小根堆。然后,将其余的元素插入到小根堆即可。插入方法如下:

/*maintain the top N numbers*/
void MinInsert(uint32_t* array, uint32_t heapSize, uint32_t elem)
{
	if(elem > array[0])
	{
		array[0] = elem;
		MinHeapify(array, heapSize, 0);
	}
}


利用大根堆解决获取大量数据中最小的N个值,先构建一个拥有N个元素的大根堆。然后,将其余的元素插入到大根堆即可。插入方法如下:

/*maintain the low N numbers*/
void MaxInsert(uint32_t* array, uint32_t heapSize, uint32_t elem)
{
	if(elem < array[0])
	{
		array[0] = elem;
		MaxHeapify(array, heapSize, 0);
	}
}

时间复杂度分析

堆调整一次的时间复杂度是O(logN)。所以,通过堆来解决top N 问题的时间复杂度是O(nlogN).

其中,n为数据的个数,N为堆维护的数据的个数。

 

测试程序

int main()
{
	int i = 0, heapSize = 10;
	uint32_t array[] = {2,20,13,18,15,8,3,5,4,25};
	uint32_t minelem = 10, maxelem = 1;

/*build min heap and test insert*/
	MinHeapCreat(array, heapSize);  
	printf("Output the MinHeap:\n");  
	for(i = 0; i < heapSize; i++)  
	{  
		printf("%d\t", array[i]);  
	}  
	MinInsert(array, heapSize, minelem); 
	printf("\nOutput insert elem %d:\n",minelem);
	for(i = 0; i < heapSize; i++)
	{
		printf("%d\t", array[i]);
	}
	printf("\n");
/*build max heap and test insert*/
	MaxHeapCreat(array, heapSize);    
	printf("Output the MaxHeap:\n");    
	for(i = 0; i < heapSize; i++)    
	{    
		printf("%d\t", array[i]);    
	}    
	MaxInsert(array, heapSize,maxelem);	
	printf("\nOutput insert elem %d:\n",maxelem);    
	for(i = 0; i < heapSize; i++)    
	{    
		printf("%d\t", array[i]);    
	}
	printf("\n"); 
}

测试结果

AD17入门简单教程(一) AD17入门简单教程 我写这篇文章主要是因为最近刚学习完了AD17,想做一下总结,也希望通过自己心得的帮助一些刚入门AD17的小白。 总结一共分为两大部分,包括AD17的下载安装与汉化(文末有详细链接)、工程的创建、元器件库、PCB、走线中的常用命令介绍,文末还附有完整的PCB工程以及讲解视频。 第一部分工程的创建及元器件库常用命令 1.首先在桌面上创建一个文件夹,然后在AD17点击左上角的文件中... 阅读详情

相关推荐

Win11家庭版如何让Win+R运行CMD默认管理员权限?3种方法实测有效

本文针对Win11家庭版用户,实测了三种让Win+R运行CMD默认获取管理员权限的有效方法。通过分析UAC机制与家庭版功能限制,详细介绍了注册表编辑、快捷方式创建与任务计划程序三种方案的原理、步骤与风险对比,帮助用户根据安全与效率需求选择最佳方案,实现一键高效管理。

sat99的博客 1267

大顶堆和小顶堆

一、什么是堆? 堆是一种非线性结构,可以把堆看作一棵二叉树,也可以看作一个数组,即:堆就是利用完全二叉树的结构来维护的一维数组。 堆可以分为大顶堆和小顶堆。 大顶堆:每个结点的值都大于或等于其左右孩子结点的值。 小顶堆:每个结点的值都小于或等于其左右孩子结点的值。 如果是排序,求升序用大顶堆,求降序用小顶堆。 一般我们说 topK 问题,就可以用大顶堆或小顶堆来实现, 最大的 K 个:小顶堆 最小的 K 个:大顶堆这里是引用 二、PriorityQueue 常用的方法: 大根堆的构造 Priori

m0_51436734的博客 5329

基于STM32 HAL库的L298N四驱电机PWM调速与方向控制实战

本文详细介绍了基于STM32 HAL库驱动L298N电机控制板实现四驱小车PWM调速与方向控制的实战方法。涵盖硬件连接、GPIO与定时器配置、PWM生成、方向控制逻辑及电源管理等核心内容,并提供代码优化与常见问题解决方案,帮助开发者快速实现高效稳定的电机控制。

jump7的博客 222

大根堆和小根堆的区别

堆的概念堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:Key[i]&lt;=key[2i+1]&amp;&amp;Key[i]&lt;=key[2i+2]或者Key[i]&gt;=Key[2i+1]&amp;&amp;key&gt;=key[2i+2]即任何一非叶节点的关键字不大于或者不小于其左右孩子节点的关键字。堆分为大顶堆和小顶堆,满足Key[i]&gt;=Key[2i+1]&amp;&...

weixin_37197708的博客 1万+

论文阅读|《强化学习在加工时间可变的机器人流水车间调度中的应用》

《Reinforcement Learning for robotic flow shop scheduling with processing time variations》 International Journal of Production Research/2021 1 摘要 我们解决了一个机器人流水车间调度问题,其中两种零件类型在每组给定的专用机器上进行处理。单个机器人在固定轨道上移动,一次运输一个部件,在给定的时间间隔内,这些部件在机器上的加工时间各不相同。我们使用强化...

太剧烈的快乐与太剧烈的悲哀是有相同之点的——同样地需要远离人群! 2929

别再怕DRIVER_VERIFIER_DMA_VIOLATION蓝屏:手把手教你用WinDbg分析IOMMU与驱动冲突

本文深入解析DRIVER_VERIFIER_DMA_VIOLATION蓝屏错误,从IOMMU原理到实战排错,手把手教你使用WinDbg分析驱动冲突。通过理解DMA与IOMMU的核心机制、搭建分析环境、解读DMAR表与设备拓扑,最终定位问题驱动并提供解决方案,帮助开发者和IT运维人员有效应对此类系统崩溃问题。

weixin_30298497的博客 802

大顶堆 小顶堆 堆排序

基础知识 大顶(根)堆与小顶(根)堆都是一种数据结构,它们都是完全二叉树,但是不是用指针链表形式的二叉树,而是使用顺序存储的数组存储元素值。大顶堆及堆顶元素为整个堆中的最大值,小顶堆同理,它可以在O(1)时间内获取最大值。下面以大顶堆讲解一些堆的相关知识,并给出大、小顶堆的代码。 首先,既然是顺序存储,且又是完全二叉树的结构,其节点如何存储呢?此处使用二叉树的层次遍历方式存储节点值,本文使用的节点...

shahuzi的博客 822

(一)Tushare Pro教程:股票基本数据接口

 一直使用tushare作数据源,这里开个教程大家一起学习。 一、介绍        tushare是一个python股票数据源,现已升级到tushare pro版本,新版本在数据稳定性和获取速率上大幅提升。与wind、东财等收费数据源相比,tushare pro算是金融数据界的良心之作,其为从事金融工程、量化研究等方向的同学们提供了便利。tushare pro还有一点突出的特色就是已经将股票...

虎毛的博客 4万+

关于“堆”,看看这篇文章就够了(附堆的两种应用场景)

堆(heap)是计算机科学中一类特殊的数据结构的统称,堆通常是一个可以被看做一棵树的数组对象,因此堆常常是通过数组的形式来实现的,不过堆在实现时必须遵守两个原则:1.要么是大根堆(大堆) 2.要么是小根堆(小堆)。堆总是一棵完全二叉树,堆在实现时的基本功能有 入堆、出堆、查看堆顶元素及大小、判空 等,不过堆通常不单独使用,常常是作为一种辅助结构来处理现实中的问题,比如`堆排序`和`Top-K问题`

北 海的博客 8864

qq对接openclaw,通过qq发送命令

把 OpenClaw 接入 QQ 和微信,目前主流的微信文章和教程主要提供了两种截然不同的路径。我为你梳理了它们的核心区别和关键步骤,你可以根据自己的需求来选择。

suny8的专栏 270

【Coze搞钱实战】24. 从零实现精准用户画像:Coze+企业微信打造智能导购推送系统(附完整代码)

电商运营中,“客服重复询问用户需求、无法精准推荐”是转化率低的核心痛点——日均200人次咨询,73%的问题是重复的,首单转化率仅14%。本文基于Coze平台sys_uuid用户识别功能、企业微信API与多维表格,打造“用户行为→自动打标→标签存储→智能推送”全链路方案:通过分类分层标签体系捕捉用户偏好,Coze自动识别用户并打标,飞书多维表格存储标签数据,企业微信触发个性化推送。实操后可使客服重复询问率下降62%,意向客户转化率提升81%,首单转化率提升64%。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 542

优先级队列:堆 大根堆小根堆 代码及其应用。

11

ETpgmer的博客 696

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

大根堆小根堆&TopK问题

首先明确几个概念: 大根堆也叫大顶堆,小根堆也叫小顶堆。 大根堆用于升序排序(所以求最小的前k个数用大根堆),小根堆用于降序排序(所以求最大的前k个数(常见的topk问题,基本都是求最大的前k个数)用小根堆)。 堆排序的时间复杂度是O(NlogN),空间复杂度是O(1),所以在海量数据及内存不足的条件下,该排序方法适用。 详细的实操内容可参考这篇优秀博文:https://blog.csdn...

qq_32100465的博客 5211

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

堆——神奇的优先队列 大根堆小根堆详解,附小根堆C++代码实现与STL相关

文章目录前置知识堆操作小根堆插入代码实现小根堆删除代码实现测试代码STL实现——priority_queue1.使用2.创建3.成员函数 前置知识 堆是一个完全二叉树(最后一层可以不满,上面的每一层都是满的。一个结点若只有一个孩子结点,那一定是它的左孩子。如下图)这是一个逻辑上基于完全二叉树、物理上一般基于线性数据结构(如数组、向量、链表等)的一种数据结构。 完全二叉树最重要的性质:如果n个节点的完全二叉树的节点按照层次并按从左到右的顺序从0开始编号,对于人一个绩点都有: 序号为0的节点是根 对

哇咔咔的博客 8948

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

小根堆,大根堆,堆排序

小根堆,大根堆,堆排序 下面用c++模板实现小根堆,大根堆,堆排序功能, 可以适用不同类型的数据,可以直接使用 //file:heap.h #ifndef _AGILE_HEAP_H_ #define _AGILE_HEAP_H_ #include #include typedef bool(*EqualFunc)(void*, void*); typede

myojbook的专栏 1363

关于大根堆 (模板)

嗯... 大根堆这个东西吧,可以看成是一个优先队列(priority_queue)... 为什么要用堆这个东西?? 功能强大,可排序,并且能对更大值进行操作 但是比队列慢!! 注意 若A的功能大于B的功能,那么A的速度一定比B的速度慢 上代码!!! 1 #include<cstdio> 2 #includ...

weixin_33713707的博客 246

一问教你熟练掌握大根堆和从小到大的排序VS小根堆和从大到小的排序

大根堆(Max-Heap):堆顶是最大元素。用于频繁取最大值的场景,如优先队列。从小到大的排序(Ascending Order):将元素按从小到大的顺序排列,常见排序算法默认都是这个顺序。小根堆(Min-Heap):堆顶是最小元素。用于频繁取最小值的场景,如优先队列。从大到小的排序(Descending Order):将元素按从大到小的顺序排列,可以通过改变排序算法的比较器来实现。

Frank---7的博客 861

用PriorityQueue类构造大根堆和小根堆-Java

1、大顶堆:头部为堆中最大的值 2、小顶堆:头部为队中最小的值 3、PriorityQueue:一个具有优先级的队列,该优先级使得队列始终按照自然顺序进行排序,队列的头部为最小值。 构建小根堆。 PriorityQueue small=new PriorityQueue<>(); 构建大根堆。 PriorityQueue pq = new PriorityQueue((a, b) -> b - a); ...

实用ai技巧 1837

贪心算法,优先队列(大小根堆使用)

贪心算法在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。简单来说,就是“每一步都只看眼前利益,做出当前最好的选择,不考虑长远”。核心:每一步都选择当前最优解。关键:问题必须具有贪心选择性质和最优子结构。难点:如何选择和证明贪心策略的正确性。座右铭:“活在当下”,但前提是“当下”的选择能通向往“美好的未来”。#include <functional> // 需要包含这个头文件// 小根堆的定义方式// 输出 1 (当前最小值)

Einsail的博客 885

数据结构_深入理解堆(大根堆 小根堆)与优先队列:从理论到手撕实现

本文系统介绍了堆数据结构及其应用。首先阐述了大根堆和小根堆的概念与特性,强调其完全二叉树结构和父节点与子节点的大小关系。其次详细讲解了优先队列的实现原理,包括其核心操作(插入、删除、访问)和基于堆的高效实现方法。最后通过代码示例展示了手写优先队列的关键实现细节,包括向上/向下调整、堆排序等算法。文章内容覆盖了堆的理论基础、操作特性和实际应用,为理解和使用这一重要数据结构提供了全面指导。

努力码字中······ 1023

【暖*墟】 #二叉堆# 大根堆的常见操作

一、二叉堆的定义 二叉堆使用完全二叉树(其前n-1层必须被填满,第n层也要从左到右顺序填满)来实现。 在二叉堆中,所有非终端结点的值均不大于(或不小于)其左右孩子的值。 若非终端结点的值均不大于其左右孩子结点的值,这样的二叉堆叫做小根堆(下图b), 小根堆根结点的值是该堆中所有结点的最小值; 同样的,若非终端结点的值都不小于其左右孩子的值,这样的堆叫做大根堆(下图a), 大根堆根结点的...

flora715的博客 588

数据结构 之 二叉堆

一、二叉堆简介:   二叉堆故名思议是一种特殊的堆,二叉堆具有堆的性质(父节点的键值总是大于或等于(小于或等于)任何一个子节点的键值),二叉堆又具有二叉树的性质(二叉堆是完全二叉树或者是近似完全二叉树)。当父节点的键值大于或等于(小于或等于)它的每一个子节点的键值时我们称它为最大堆(最小堆),或者是大根堆(小根堆)。       二叉堆多数是以数组作为它们底层元素的存储。 假如根节点在数

小邓笔记 2353

堆排序python实现_[151225] Python3 实现最大堆、堆排序,解决TopK问题

参考资料:大(小)根堆:是完全二叉树,也是大(小)根树。大小根堆的差异,主要表现在 比较函数的差异上。大根堆的操作:插入(nlog(n)):概述:把新元素val作为新节点,沿着新节点到根节点的路径,执行一趟冒泡排序。即:将新元素与父节点的元素进行比较交换,直到父节点不小于子节点为止。删除(nlog(n)):目的:删除最大值即根节点root。(1)首先换首尾节点,然后删除尾结点;(2)并从根节点出发...

weixin_39926739的博客 240

堆排序

一  大根堆与小根堆以及知识点 大根堆(大顶堆):是一颗完全二叉树,其父亲节点总是比叶子节点大。也就是大根堆的根节点最大 小根堆(小顶堆):是一颗完全二叉树,其父亲节点总是比叶子节点小。也就是大根堆的根节点最小 对一颗完全二叉树来说:length/2必为最大的非叶子节点,1为根节点,对父亲节点k来说,2*k 和2*k+1为其叶子节点。 二 说明 对需要进行从小到大排序的数组来说,

hl2015222050145的博客 458
上一篇: VIM窗口分屏
下一篇: 堆的动态创建与根节点删除
IT_Linux
博客等级 码龄14年 31粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值