stl源码剖析 详细学习笔记heap

STL源码剖析(侯杰)——读书笔记 文章目录STL源码剖析(侯杰)——读书笔记1. STL概论2.空间配置器SGI标准空间配置器, std::allocatorSGI特殊的空间配置器, std::alloc构造和析构 construct()和destroy()空间配置与释放3.迭代器概念与traits编程概念迭代器相应型别传递Traits编程技法——STL源码门钥Partial Specialization(偏特化)的意义std::iterator的保证4.序列式容器vector**list**dequestackqueueheappri 阅读详情

//

//  heap.cpp

//  笔记

//

//  Created by fam on 15/3/15.

//

//


//---------------------------15/03/15----------------------------



//heap

{

    /*

        heap概述:

        heap并不是stl的容器,只是priority queue(优先队列)的助手

        它允许用户以任意顺序插入容器,但是取出是,总是取出优先级最高的元素

        heap用的是很常见的堆结构,用数组来表示,采用堆排序的方法排序,时刻保持堆的特性

     */

    

    

    

    //push_heap

    template <class RandomAccessIterator>

    inline void push_heap(RandomAccessIterator first,

                          RandomAccessIterator last)

    {

        __push_heap_aux(first,last, distance_type(first),

                        value_type(first));

        

    }

    

    template <class RandomAccessIterator, class Distance, class T>

    inline void __push_heap_aux(RandomAccessIterator first,

                                RandomAccessIterator last, Distance*,T*)

    {

        __push_heap(first,Distance((last - first) - 1), Distance(0),

                    T(*(last - 1)));

    }

    

    template <class RandomAccessIterator, class Distance, class T>

    void __push_heap(RandomAccessIterator first, Distance holeIndex,

                     Distance topIndex, T value)

    {

        //取最后一个元素的父节点,先减1的原因是第一个节点时0,

        //而不是1开始算的

        Distance parent = (holeIndex - 1) / 2;

        

        //一直循环到当前节点等于根节点 或者 父节点的值大于等于添加的值

        while (holeIndex > topIndex && *(first + parent) < value)

        {

            // 把父节点的值赋值给当前节点

            *(first + holeIndex) = *(first + parent);

            

            //当前节点变成父节点

            holeIndex = parent;

            

            //父节点变成父节点的父节点

            parent = (holeIndex - 1) / 2;

        }

        //把值赋值给恰当的位置

        *(first + holeIndex) = value;

    }

    

    //push功能总结:push就是从最后一个元素开始一直和父节点比较,如果要插入的值(最后一个元素的值)

    //比较大就不断上移,直到达到堆的根

    

    //pop_heap

    template <class RandomAccessIterator>

    inline void pop_heap(RandomAccessIterator first,

                          RandomAccessIterator last)

    {

        __pop_heap_aux(first,last,value_type(first));

        

    }

    

    

    template <class RandomAccessIterator, class T>

    inline void __pop_heap_aux(RandomAccessIterator first,

                                RandomAccessIterator last, T*)

    {

        __pop_heap(first,last - 1,last - 1, T(*(last - 1))

                    distance_type(first));

    }

    

    template <class RandomAccessIterator, class T, class Distance>

    inline void __pop_heap(RandomAccessIterator first,

                           RandomAccessIterator last,

                           RandomAccessIterator result,

                           T value, Distance*)

    {

        *result = *first;

        __adjust_heap(first, Distance(0), Distance(last - first), value);

    }

    

    

    template <class RandomAccessIterator, class Distance, class T>

    void __adjust_heap(RandomAccessIterator first, Distance holeIndex,

                       Distance len, T value)

    {

        //topIndex == 0   -->>   topelem == first + 0

        Distance topIndex = holeIndex;

        

        //由于从0开始计算 所以右儿子为 2n + 2;

        //secondChild 其实也是Index,不是真的值

        

        Distance secondChild = 2 * holeIndex + 2;

        

        //只要右儿子存在就一直循环

        while (secondChild < len)

        {

            //如果有右儿子小于左儿子,secondChild就设置为左儿子

            //目的是要让当前节点最后成为2个节点中最大的

            if(*(first + secondChild) < *(first + (secondChild - 1)))

                secondChild--;//为什么不是 --secondChild,这样效率更高

            

            //把当前节点的值设置为secondChild的值

            *(first + holeIndex) = *(first +secondChild);

            

            //当前节点切换成secondChild节点

            holeIndex = secondChild;

            

            //设置secondChild为右儿子

            secondChild = 2* (secondChild + 1);

        }

        

        //存在左儿子(如果有右儿子就会一直循环,最后只有两种情况,一是当前节点到达叶子节点

        //一种情况是没有右儿子,但是有左儿子)

        if(secondChild == len)

        {

            //把左儿子的值赋给当前节点

            *(first + holeIndex) = *(first + (secondChild - 1));

            

            //把当前节点切换成左儿子

            holeIndex = secondChild -1;

    

        }

        

        //把当初标记的最后的一个节点插入堆中( T(*(last - 1)  )

        __push_heap(first, holeIndex, topIndex, value);

        

        /*

            总结:把根节点输出到result中 所以就要不断把儿子往上移来填充

            填充到最后就会空缺一个节点(下面的往上移动总会有一个空缺的)

            所以最后要把最后的一个元素插入到堆前面去,也就是最后空缺的是原先

            最后面的位置,那就没影响了

            如果空缺的已经是最后的元素了,那就是对已经排序好的堆做排序(最后的元素

            已经比父节点大了,会马上排好.

        */

        

    }

    

    

    //sort

    

    template<class RandomAccessIterator>

    void sort_heap(RandomAccessIterator first,

                   RandomAccessIterator last)

    {

        

        while (last - first > 1)

        {

            pop_heap(first, last--);

        }

    }

    

    //结束后就是已经排序好的序列,就不是堆了

    

    

    

    //make_heap

    

    template<class RandomAccessIterator>

    inline void make_heap(RandomAccessIterator first,

                          RandomAccessIterator last)

    {

        __make_heap(first, last, value_type(first), distance_type(first));

    }

    

    template<class RandomAccessIterator, class T, class Distance>

    void    __make_heap(RandomAccessIterator first,

                        RandomAccessIterator last, T*,Distance*)

    {

        //判断边界情况,如果只有一个元素 直接返回

        if(last - first < 2) return;

        

        //len==元素个数

        Distance len = last - first;

        

        //parent == 最后一个元素的父节点

        Distance parent = (len - 2) / 2;

        

        while (true)

        {

            //一直循环,直到全部排序好,从最后的三角形(最后的元素,父节点,左儿子(如果有的话))

            //开始,直到根节点,就调整完毕了

            __adjust_heap(first, parent, len, T(*(first + parent)));

            if(parent == 0) return ;

            parent--;

        }

    }

    


    

    

}


STL源码剖析---sort_heap 一、背景 场景1:某个容器允许用户以任何次数将任何元素放入容器内,但取出时一定是从数值最大的元素开始取。优先级队列priority queue不就是想干这样的事吗? 1.1 动脑筋 容器最重要的动作是放入元素和取出元素。如果放入元素时不加处理的话,取出元素时就需要进行遍历,只需要将容器扫描一趟,我同样可以取出最大元素。放入元素的时间复杂度是O(1),取出元素的时间复杂度是O(n)。 我们也... 阅读详情

相关推荐

【STL】Heap算法——push_heap、pop_heap、sort_heap、make_heap

C++STL算法提供make_heap, push_heap和pop_heap等算法,它们作用于随机存取迭代器。它们将迭代器当做数组的引用,并做出array-to-heap的转换。STL中默认这个算法为最大堆(max_heap)。 make_heap make_heap 的功能是将一段现有的数据转化成一个heap(堆)。默认状态下,它会生成一个最大堆结构,我们也可以自己定义为最大堆或者最小堆。

LLZK_的博客 3336

STL源码分析之heap大根堆

前言 在分析本节之前你至少应该对堆排序有所了解, 大根堆, 小根堆等. 本节分析的heap就是堆排序, 严格意义上来讲heap并不是一个容器, 所以他没有实现自己的迭代器, 也就没有遍历操作, 它只是一种算法. 代码来自stl_heap.h. heap分析 push插入元素 插入函数是push_heap. heap只接受RandomAccessIterator类型的迭代器. 注意, 在分析heap...

啦啦啦 944

STL源码剖析——STL算法stl_algo.h

本文剖析的STL算法的源码,在剖析源码的同时会给出一些例子,这样加深对其理解,方便我们对这些算法的使用。

关注校招求职,微信号:job_campus 4002

STL heap部分源代码分析

本文假设你已对堆排序的算法有主要的了解。 要分析stl中heap的源代码的独到之处。最好的办法就是拿普通的代码进行比較。话不多说,先看一段普通的堆排序的代码: //调整大顶堆。使得结构合理 void max_heap(int a[],int node,int size) { int lg=node; int l=node*2; int r=node*...

weixin_33953249的博客 150

储能逆变器动态无功补偿:从原理到算法实现

本文深入解析了储能逆变器动态无功补偿的核心原理与算法实现。通过四象限运行与解耦控制技术,储能逆变器可在充放电的同时,快速、精准地调节无功功率,有效提升电网电能质量与功率因数。文章详细阐述了从相位调节、容量限制到PI控制算法的完整技术路径,并结合工程实践,探讨了其在光伏/储能系统中的协同控制策略与进阶应用价值。

weixin_29216353的博客 207

画个板子玩一玩STM32F030F4P6,也许是最便宜的32bit MCU

前言,什么是STM32F030F4P6 STM32目前最便宜的芯片之一应该就是这一块,STM32F030F4P6,这一个芯片没有USB,但是其他都有,引脚少,价格低廉,如果找不到原厂,可以买替代的国产芯片,性能也一样。 不管怎么样也是Cortex-M0,比8bit和16bit的性能都强,总的来说就是低价,引脚少,体积小的同时,还容易开发,有很多模拟输入可玩,还有SPI,硬件I2C等等 所以,这一款MCU真的是从理论来说又便宜又好用,非常适合把玩。 画个板,最小系统 STM32F030其..

arenascat的博客 2万+

《STL源码剖析》笔记-priority_queue、heap算法

上一篇:《STL源码剖析》笔记-stack、queue priority_queue是一个带权值的队列,权值最高的自动排在最前面,默认排序从大到小,同时具有队列先进先出、没有迭代器的特性。priority_queue也是一种container adapter,底层容器默认为vector。 stack定义完整列表 // 排序方式less(从大到小),也能指定为greater(从小到大) templa...

WizardtoH 591

HALCON深度学习模型部署新选择:一份详细的OpenVINO 2021.4 LTS集成与配置避坑指南

本文详细介绍了如何将HALCON深度学习模型与OpenVINO 2021.4 LTS集成,提供环境配置、硬件加速优化及故障排除的实用指南。特别针对Intel独立显卡的AI加速器接口进行优化,帮助机器视觉工程师提升AI推理效率,适用于工业检测等高要求场景。

weixin_42531779的博客 238

《STL源码剖析》学习笔记——第四章:序列式容器 heap

目录 1. heap概述 2. heap算法 2.1push_heap算法 2.2 pop_heap 2.3sort_heap 2.4make_heap 3. heap测试实例 1. heap概述 heap并不归属于STL容器组件,扮演priority queue的助手,binary max heap适合作为priority queue的底层机制,priority queue允许用户以任意次序将元素推入容器,但是取出是一定是优先权最高(数值最高)的元素先出来。binary heap是...

baidu_15952103的博客 422

【多模态融合】TransFusion学习笔记(1)

工作上主要还是以纯lidar的算法开发,部署以及系统架构设计为主。对于多模态融合(这里主要是只指Lidar和Camer的融合)这方面研究甚少。最近借助和朋友们讨论论文的契机接触了一下这方面的知识,起步是晚了一点,但好歹是开了个头。下面就借助TransFusion论文及其开源代码来串一串这方面的知识。这个很好理解,参考FPointNet网络图示。就是利用现有的2D检测器在图像上提取2D初始框,根据Camera成像原理,捕获2D框视锥内的点云,再利用点云分类模型(如:PointNet)做进一步分类。

4961

autodl云服务器使用中的conda源报错

通过find path -name filename找到.condarc文件,在autodl服务器中,一般在/root/.condarc。为了利用jypyter打开conda虚拟环境运行,需要下载ipykenel。这个报错是源的问题,在通过源获取包元数据时出现了HTTP 429错误。通过conda换源解决。修改.condarc文件,命令: vim .condarc。但这样还不能解决问题,得把报错中有问题的源注释掉。通过以下命令添加清华镜像源。把报错的链接源注释如下。

Ty_kilig的博客 1584

【STL源码剖析】从源码看 heap:元素的 “下沉” 与 “上浮”

本文深入剖析了STL中heap的实现原理与核心算法,适合已掌握C++模板和STL基础的开发者。文章介绍了binary heap的完全二叉树特性及其数组存储方式,重点分析了大顶堆(max-heap)的实现。核心内容包括:1) push_heap的上溯调整算法,通过父节点比较完成元素插入;2) pop_heap的下溯调整策略,结合根节点交换与末尾元素删除;3) 基于pop_heap实现的堆排序原理。通过源码解析揭示了STL高效堆操作的关键设计:迭代器包装、节点位置计算和调整优化技巧。

2401_87944878的博客 2万+

Windows 上 openclaw onboard --install-daemon 命令的安装位置和启动配置

摘要:Windows系统中,执行openclaw-cnonboard--install-daemon命令会创建计划任务OpenClawGateway,该任务在用户登录时自动运行位于%USERPROFILE%.openclaw\gateway.cmd的脚本文件来启动服务。管理方法包括通过任务计划程序或命令行(schtasks)查看/启停任务,使用openclaw gateway命令操作服务,或通过删除计划任务和脚本文件完全卸载服务。该机制确保OpenClawGateway服务随系统登录自动启动。(149字)

大坡3D软件开发 1375

STL源码剖析——heap

Heap堆是常用的数据结构,Heap中也可以存放元素。但是STL中并没有提供Heap容器,只是提供了关于Heap操作的算法。只要支持RandomAccessIterator的容器都可以作为Heap容器。 Heap分为max heap和min heap,max heap中每次取出的结点时heap结构中值最大的结点,min heap中每次取出的结点时heap结构中值最小的结点。 在实际应用中,经常

Smile&搁浅 2734

Allegro Design Entry HDL(OrCAD Capture HDL)原理图是设计快速入门图文教程

Allegro Design Entry HDL是Cadence公司开发的原理图设计工具,也可与Allegro PCB设计工具无缝对接,虽然板级开发中不如Design Entry CIS(又名 OrCAD Capture CIS)的使用那么广泛,但是由于Design Entry HDL支持芯片的开发,所以有不少公司尤其是芯片背景公司,选择使用Design Entry HDL进行原理图设计。两个原理图开发工具的使用方法大同小异,本文简单介绍使用Allegro Design Entry HDL开始一个新的设计,

fydar的博客 4127

YOLO11全网首发:CVPR2026 MixerCSeg | DEGConv方向引导边缘门控,破解细长裂缝检测难题

DEGConv通过方向先验嵌入、边缘增强卷积和动态门控三大机制,针对性解决了YOLO在处理裂缝类细长、多方向、低对比度目标时的特征提取不足问题,显著提升了裂缝检测的精度与鲁棒性。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 561

STL 源码剖析 heap堆

heap不属于STL容器的组件,属于幕后角色,是priority_queue的助手 priority_queue 允许用户以任何次序将任何元素推入容器内,但是取出的时候需要从优先级最高(也就是数值最高)的元素开始取,这种思想是基于heap的函数实现 如果使用list作为priority_queue 的底层实现机制,元素的插入操作可以使用常数的时间,但是不好找 极值,需要进行线性扫描和遍历;如果考虑到大小这个关键因素,进行元素的排序,随后进行元素之间的衔接,降低了元素的插入效率 使用binary se.

CHYabc123456hh的博客 1617

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

STL源码剖析——最大堆heap

前言

关注校招求职,微信号:job_campus 1477

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

STL源码剖析笔记——Binary Heap、priority_queue

STL源码剖析笔记——Binary Heap、priority_queue

weixin_48956191的博客 1449

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

优先级队列核心!STL heap算法源码剖析

一、heap概述 heap并不归属于 STL 容器组件 binary heap作为priority queue的底层实现机制。顾名思义,priority queue允许使用者以任何次序将任何元素推入容器内,但取出时一定是从优先权最高(也就是数值最高)之元素开始取。binary max heap正是具有这样的特性,适合做为priorityqueue的底层机制 heap作为priority qu...

董哥的黑板报 1525

STL 源码剖析第四章 —— heap(堆) 详解

在 STL 中,heap 不是独立的容器类型,而是一组作用于序列容器(通常是 vector)的算法:注意事项:堆是一种特殊的完全二叉树,满足以下性质:堆通常用数组或动态数组(如 )实现,利用完全二叉树的特性进行紧凑存储。节点关系通过索引计算:假设数组 表示一个最大堆:这种表示方法节省空间且支持高效遍历。 图 2-1 deque的数据结构示意图STL 中的 heap 操作通过算法实现,而非独立容器。这些算法通常作用于 或动态数组上,通过随机访问迭代器操作。核心算法包括 、、 和 ,均位于 头文件中

weixin_52227132的博客 801

STL之priority_queue源码剖析

STL之priority_queue源码剖析 heap 在探讨priority_queue之前,我们必须先分析heap。heap并不归属于STL容器,他是个幕后英雄,扮演priorityqueue的助手。顾名思义,priority queue允许用户以任何次序将任何元素推入容器,但取出时一定是从优先权最高的元素开始取。Binary max heap证据有这样的特性,适合作为priority_q

walkerkalr的专栏 2541

STL源码剖析----heap

heap就是一个基础容器+heap算法,array和vector都可以作为heap的基础容器,vector可以动态改变容量,比array会更好。 heap并不归属STL容器,它只是在priority queue容器里起辅助作用,priority queue把heap作为底层机制,可以更好地完成它接口里的一些操作。 binary heap就是一种完全二叉树,就是除了最底层的叶子节点外,都是填满的,且...

yde的博客 289

STL heap

Heap堆是常用的数据结构,Heap中也可以存放元素。但是STL中并没有提供Heap容器,只是提供了关于Heap操作的算法。只要支持RandomAccessIterator的容器都可以作为Heap容器。 Heap分为max heap和min heap,max heap中每次取出的结点时heap结构中值最大的结点,min heap中每次取出的结点时heap结构中值最小的结点。 Heap不允许遍历其结点,所以Heap没有迭代器。 在实际应用中,经常用vector作为heap容器,heap经常作为prior

qq_41078889的博客 1425
上一篇: stl源码剖析 详细学习笔记stack queue
下一篇: stl源码剖析 详细学习笔记priority_queue slist
boydfd
博客等级 码龄16年 101粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值