当前位置: 首页 > news >正文

数据结构—堆(完全解析)

数据结构—堆(完全解析)

数据结构——堆(Heap)大根堆、小根堆

详解数据结构——堆

堆的基本存储

【从堆的定义到优先队列、堆排序】 10分钟看懂必考的数据结构——堆

【堆/排序】堆排序的两种建堆方法

【算法】排序算法之堆排序

C++:浅析STL之priority_queue构建大根堆与小根堆

基本概念

堆通常是一个可以被看做一棵完全二叉树的数组对象

堆满足下列性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值
  • 堆总是一棵完全二叉树

Min-heap(大根堆): 父节点的值小于或等于子节点的值

Max-heap(小根堆): 父节点的值大于或等于子节点的值
在这里插入图片描述

堆的存储

一般都用数组来表示堆,i结点的父结点下标就为(i–1)/2

它的左右子结点下标分别为2 * i + 1和2 * i + 2

如第0个结点左右子结点下标分别为1和2

在这里插入图片描述

堆的插入和上浮

  • 当一个新元素想要插入这个堆的时候,我们首先把他放到这个堆的末尾
  • 然后依据堆的特性,对它的位置进行调整,由于要保持父结点的值要永远少于其子节点的值,而2的直接父节点6大于了它,所以要把他们两的位置对换
  • 对换完毕后,再检查这个堆的状态,发现其父节点3仍然大于自己,所以继续往上和3对换
  • 结束后和0比较,0不大于自己,所以停留在原地不动,插入结束
  • 简单来说,插入一个结点就是将该元素插入到堆的尾部,然后不断上浮调整位置,直至满足堆的条件

在这里插入图片描述

堆的删除和下沉

  • 删除一般指的都是删除堆顶元素,在堆顶元素被拿掉后,将末尾元素置换上来,进行下沉操作
  • 由于这是最小堆,堆顶一定是最小元素,首先6大于左结点1,需要下沉,
  • 下沉完以后继续和它子节点比较,发现左结点2小于自身,继续下沉
  • 最后89都比6大,停止下沉。
  • 总结来说,意思就是删除堆顶元素后,用末尾元素补上,然后不断下沉,直至满足堆的条件

在这里插入图片描述

堆的建立

自顶向下,时间复杂度为O(nlogn)

在这里插入图片描述
自下而上,时间复杂度为O(n)

从倒数第二排开始,对每一个父节点进行下滤操作,直到根节点操作完毕

在这里插入图片描述
在这里插入图片描述

堆的应用

优先队列

优先队列有两个操作,插入队列和弹出最小元素

在这里插入图片描述

优先队列利用小根堆实现,弹出根节点即可实现弹出最小元素的操作

在这里插入图片描述

弹出后要将剩余的元素调整为堆,将最后一个元素放到根节点,进行下沉操作即可

在这里插入图片描述
在这里插入图片描述

堆排序

  • 先把数组构造成一个大顶堆(父亲节点大于其子节点),然后把堆顶(数组最大值,数组第一个元素)和数组最后一个元素交换,这样就把最大值放到了数组最后边
  • 把数组度-1,再进行构造堆把剩余的第二大值放到堆顶,输出堆顶(放到剩余未排序数组最后面),依次类推,直至数组排序完成
#include <iostream>
#include <algorithm>
using namespace std;
void max_heapify(int arr[], int start, int end) {//建立父节点指标和子节点指标int dad = start;int son = dad * 2 + 1;while (son <= end) { //若子节点指标在范围内才做比较if (son + 1 <= end && arr[son] < arr[son + 1]) //先比较两个子节点大小,选择最大的son++;if (arr[dad] > arr[son]) //如果父节点大于子节点代表调整完毕,直接跳出函数return;else { //否则交换父子内容再继续子节点和孙节点比较swap(arr[dad], arr[son]);dad = son;son = dad * 2 + 1;}}
}
void heap_sort(int arr[], int len) {//初始化,i从最后一个父节点开始调整for (int i = len / 2 - 1; i >= 0; i--)max_heapify(arr, i, len - 1);//先将第一个元素和已经排好的元素前一位做交换,再从新调整(刚调整的元素之前的元素),直到排序完毕for (int i = len - 1; i > 0; i--) {swap(arr[0], arr[i]);max_heapify(arr, 0, i - 1);}
}
int main() {int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };int len = (int) sizeof(arr) / sizeof(*arr);heap_sort(arr, len);for (int i = 0; i < len; i++)cout << arr[i] << ' ';cout << endl;return 0;
}

C++ STL大根堆小根堆

在C++中优先队列默认的是大根堆,如果用小根堆则加入greater

#include <queue>
priority_queue<int, vector<int>>s;//大根堆
priority_queue<int, vector<int>, less<int>>s;//less表示按照递减(从大到小)的顺序插入元素,大根堆
priority_queue<int, vector<int>, greater<int>>s;//greater表示按照递增(从小到大)的顺序插入元素,小根堆

支持的顺序容器:vector,queue,默认是vector

priority_queue类能按照有序的方式在底层数据结构中执行插入、删除操作

q.pop();//删除优先队列priority_queuel的最高优先级元素(通过调用底层容器的pop_back()实现)
q.push(item);//在priority._queue优先级顺序合适的位置添加创建一个值为item的元素(通过调用底层容器的push_back()操作实现)
q.emplace(args);//在priority_queue优先级顺序合适的位置添加个由args构造的元素(通过调用底层容器的emplace_back()操作实现)
q.top();//返回priority_queue的首元素的引用(通过调用底层容器的front()操作实现)
q.empty();//判断q是否为空,空返回true,否则返回false(通过调用底层容器的empty()操作实现)
q.size();//返回q中的元素个数(通过调用底层容器的size()操作实现)
swap(q,p);//交换两个优先队列priority_queue p,q的内容,p和q的底层容器类型也必须相同(通过调用底层容器的swap0操纵实现)

相关文章:

数据结构—堆(完全解析)

数据结构—堆&#xff08;完全解析&#xff09; 数据结构——堆&#xff08;Heap&#xff09;大根堆、小根堆 详解数据结构——堆 堆的基本存储 【从堆的定义到优先队列、堆排序】 10分钟看懂必考的数据结构——堆 【堆/排序】堆排序的两种建堆方法 【算法】排序算法之堆排序 C…...

深度卷积对抗神经网络 进阶 第三部分 GANs Unpaired Translation with Cycle GAN 模型

非配对的图像转换应用 Unpaired Image-to-Image Translation Unpaired image-to-image translation 主要用于学习两组图像之间的对应关系&#xff0c;检查和寻找两堆数据中的共同内容&#xff08;content&#xff09;以及每堆独有的特点&#xff08;style&#xff09;。而这个…...

常见的排序算法 | 直接插入排序 | 希尔排序 | 选择排序 | 堆排序 | 冒泡排序 | 快速排序 | 归并排序 |(详解,附动图,代码)

思维导图&#xff1a; 一.插入排序 1.直接插入排序&#xff08;InsertSort&#xff09; ①手机通讯录时时刻刻都是有序的&#xff0c;新增一个电话号码时&#xff0c;就是使用插入排序的方法将其插入原有的有序序列。 ②打扑克 步骤&#xff1a; ①如果一个序列只有一个数&am…...

深入浅出 MySQL 索引(一)

MySQL 索引&#xff08;基础篇&#xff09; 你好&#xff0c;我是悟空。 本文目录如下&#xff1a; 一、前言 最近在梳理 MySQL 核心知识&#xff0c;刚好梳理到了 MySQL 索引相关的知识&#xff0c;我的文章风格很多都是原理 实战的方式带你去了解知识点&#xff0c;所以…...

FinClip 的 2022 与 2023

相比往年&#xff0c;今年复盘去年与展望新年的文章来的稍慢一点。不过也希望能够借这篇文章&#xff0c;和关注 FinClip 的用户朋友们一起聊聊&#xff0c;我们在去年和今年的想法与计划。 2022 在过去的一年中&#xff0c;我们的身边发生了很多事情&#xff0c;这些事情在不…...

Python 泛型 - 如何在实例方法中获取泛型参数T的类型?

先上解决方法&#xff1a;https://stackoverflow.com/questions/57706180/generict-base-class-how-to-get-type-of-t-from-within-instance 再来简单分析下源码。 talk is cheap, show me the code. from typing import Dict Dict[str, int]Dict只是一个类型&#xff0c;并不…...

Shell语法基础总结

Shell 变量使用变量只读变量删除变量变量类型Shell 字符串单引号与双引号字符串获取字符串长度提取子字符串拼接字符串Shell 数组定义数组读取数组获取数组的长度Shell 传递参数Shell 基本运算符算术运算符关系运算符布尔运算符逻辑运算符字符串运算符Shell 信息输出命令Shell …...

架构基本概念和架构本质

什么是架构和架构本质 在软件行业&#xff0c;对于什么是架构&#xff0c;都有很多的争论&#xff0c;每个人都有自己的理解。此君说的架构和彼君理解的架构未必是一回事。因此我们在讨论架构之前&#xff0c;我们先讨论架构的概念定义&#xff0c;概念是人认识这个世界的基础&…...

taobao.trade.ordersku.update( 更新交易的销售属性 )

&#xffe5;开放平台免费API必须用户授权 只能更新发货前子订单的销售属性 只能更新价格相同的销售属性。对于拍下减库存的交易会同步更新销售属性的库存量。对于旺店的交易&#xff0c;要使用商品扩展信息中的SKU价格来比较。 必须使用sku_id或sku_props中的一个参数来更新&a…...

算法实战应用案例精讲-【图像处理】使用scikit-image做图像处理(最终篇)(附python代码实现)

目录 高级滤波 autolevel bottomhat 与 tophat enhance_contrast entropy equalize gradient 其它滤波器...

数据结构与算法(四):树结构

前面讲到的顺序表、栈和队列都是一对一的线性结构&#xff0c;这节讲一对多的线性结构——树。「一对多」就是指一个元素只能有一个前驱&#xff0c;但可以有多个后继。 一、基本概念 树&#xff08;tree&#xff09;是n&#xff08;n>0&#xff09;个结点的有穷集。n0时称…...

taobao.trade.shippingaddress.update( 更改交易的收货地址 )

&#xffe5;开放平台免费API必须用户授权 只能更新一笔交易里面的买家收货地址 只能更新发货前&#xff08;即买家已付款&#xff0c;等待卖家发货状态&#xff09;的交易的买家收货地址 更新后的发货地址可以通过taobao.trade.fullinfo.get查到 参数中所说的字节为GBK编码的&…...

VS Code安装及(C/C++)环境配置(Windows系统)

参考资料2份&#xff1a; 从零开始的vscode安装及环境配置教程(C/C)(Windows系统)_光中影zone的博客-CSDN博客_vscode运行配置https://blog.csdn.net/qq_45807140/article/details/112862592 VSCode配置C/C环境 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/87864677 五…...

【Spring Cloud Alibaba】006-OpenFeign

【Spring Cloud Alibaba】006-OpenFeign 文章目录【Spring Cloud Alibaba】006-OpenFeign一、概述1、Java 项目实现接口调用的方法HttpclientOkhttpHttpURLConnectionRestTemplate WebClient2、Feign 概述二、Spring Cloud Alibaba 快速整合 OpenFeign1、添加依赖2、启动类加注…...

挚文集团短期内不适合投资,长期内看好

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 挚文集团&#xff08;MOMO&#xff09;在新闻稿中称自己是“中国在线社交和娱乐领域的领军企业”。 该公司旗下的陌陌是中国“陌生人社交网络”移动应用类别的领导者&#xff0c;并在2022年9月拥有超过1亿的月活跃用户。探…...

clion开发的常用快捷键以及gitcrlf的问题

前段报错&#xff1a;git config core.autocrlf false 然后删除app目录下的文件&#xff0c;除了.git文件夹然后 git bash ,执行 git reset --hardclion常用快捷键&#xff1a;Double shift 搜索文件F9调试F9运行到断点Ctrl F8 打断点F7单步步入Shift F8 单步跳出F8执行下一行代…...

LeetCode 格雷编码问题

格雷编码格雷编码的定义格雷编码的码表LeetCode 89. 格雷编码实例思路与代码思路一&#xff1a;找规律代码一代码二思路二&#xff1a;与自然数之间的关系&#xff08;你必须知道&#xff0c;这个规律要去百度才知道&#xff09;代码一LeetCode 1238. 循环码排列实例思路与代码…...

java生成html文件输出到指定位置

String fileName "filename.html";StringBuilder sb new StringBuilder();// 使用StringBuilder 构建HTML文件sb.append("<html>\n");sb.append("<head>\n");sb.append("<title>HTML File</title>\n");sb.a…...

华为OD机试用Python实现 -【微服务的集成测试】(2023-Q1 新题)

华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 微服务的集成测试…...

软考高级信息系统项目管理(高项)原创论文——整体管理(2)

<...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...