堆的实现——对的应用(堆排序)
文章目录
- 1.堆的实现
- 2.堆的应用--堆排序
大家在学堆的时候,需要有二叉树的基础知识,大家可以看我的二叉树文章:二叉树
1.堆的实现
如果有⼀个关键码的集合 K = {k0 , k1 , k2 , …,kn−1 } ,把它的所有元素按完全⼆叉树的顺序存储⽅
式存储,在⼀个⼀维数组中,并满⾜: Ki <= K2∗i+1 ( Ki >= K2∗i+1 且 Ki <= K2∗i+2 ),
i = 0、1、2… ,则称为⼩堆(或⼤堆)。将根结点最⼤的堆叫做最⼤堆或⼤根堆,根结点最⼩的堆
叫做最⼩堆或⼩根堆。
如下就是堆的例子:
堆有很多的应用,例如:①堆排序 ②TOP-K问题
堆的底层就是数组,我们主要实现如下接口:
//堆的初始化
void HeapInit(Heap* php);
// 堆的销毁
void HeapDestory(Heap* php);
// 堆的插入
void HeapPush(Heap* php, HPDataType x);
// 堆的删除
void HeapPop(Heap* php);
// 取堆顶的数据
HPDataType HeapTop(Heap* php);
// 堆的数据个数
int HeapSize(Heap* php);
// 堆的判空
int HeapEmpty(Heap* php);
堆结构:
typedef int HPDataType;typedef struct Heap
{HPDataType* _a;int _size;int _capacity;
}Heap;
对于堆的初始化和销毁很简单:
//堆的初始化
void HeapInit(Heap* php)
{assert(php);php->_a = NULL;php->_size = php->_capacity = 0;
}// 堆的销毁
void HeapDestory(Heap* php)
{assert(php);php->_capacity = php->_size = 0;free(php->_a);php->_a = NULL;
}
对于堆的插入,例如我们建一个小根堆,我们每次插入一个数,是把他放在堆尾的(即数组的最后一个元素),然后使用向上调整算法,
Q:什么是向上调整算法?
A:对于我们新插入来的数,我们把他放在堆的最后一个元素上,我们需要不断比较他(即孩子节点)与父节点谁小,若父节点小,则终止循环,若孩子节点小,则需要他和父节点交换位置,并循环下去比,代码如下:
//向上调整算法,建小堆
void AdjustUp(HPDataType* arr, int n)
{int child = n - 1;while (child > 0){int parent = (child - 1) >> 1;if (arr[child] < arr[parent]){swap(arr[child], arr[parent]);}child = parent;}
}
所以,对于堆插入一个元素代码如下:
// 堆的插入
void HeapPush(Heap* php, HPDataType x)
{assert(php);//判断是否需要增容if (php->_capacity == php->_size){int newCapacity = php->_capacity == 0 ? 4 : 2 * php->_capacity;HPDataType* tmp = (HPDataType*)realloc(php->_a, newCapacity * sizeof(HPDataType));if (tmp == NULL){perror("realloc fail");exit(-1);}php->_capacity = newCapacity;php->_a = tmp;}php->_a[php->_size++] = x;//向上调整算法AdjustUp(php->_a, php->_size);
}
对于堆的删除,也就是我们要把最小的那个元素pop出来,已知的是堆顶是最小的元素,我们只需要让堆顶元素和最后一个元素互换,然后size–,然后在执行向下调整算法即可:如下
//向下调整算法
void AdjustDown(HPDataType* arr, int n)
{int parent = 0;int child = parent * 2 + 1;while (child < n){if (child + 1 < n && arr[child + 1] < arr[child]) child = child + 1;if (arr[child] < arr[parent]){swap(arr[child], arr[parent]);parent = child;child = parent * 2 + 1;}else break;}
}// 堆的删除
void HeapPop(Heap* php)
{assert(php);assert(!HeapEmpty(php));swap(php->_a[0], php->_a[php->_size - 1]);php->_size--;AdjustDown(php->_a, php->_size);
}
余下的接口:
// 取堆顶的数据
HPDataType HeapTop(Heap* php)
{assert(php);assert(!HeapEmpty(php));return php->_a[0];
}// 堆的数据个数
int HeapSize(Heap* php)
{assert(php);return php->_size;
}
// 堆的判空
int HeapEmpty(Heap* php)
{assert(php);return php->_size == 0 ? 1 : 0;
}
2.堆的应用–堆排序
我们想一想,给我们传入一个数组,让我们堆数组里面的元素进行排序,需要注意的是,向上调整算法和向下调整算法我们都要求除了他,其他的都是一个堆。也就是我们需要对每个数据都进行一遍调整算法,那么向上还是向下呢?我们来分析一下时间复杂度:
-
向上调整算法:我们需要从第一个元素开始都进行一遍向上调算法,

因此来说:==向上调整算法的时间复杂度是O(nlogn),==为什么这么高,我们可以想一下,月考后面的元素在二叉树上呈现的是越多的,而且他还要向上移动比较的次数更多,那他的复杂度不就高了吗 -
向下调整算法:这里,我们不需要从最后一个元素开始向下调整,我们只需要从最后一个非叶子节点开始向下调整算法即可,

因此向下调整算法的时间复杂度为:O(n)
注意:这里是向下调整算法建堆的时间复杂度是O(n),但是单单一个元素向下调整算法是O(logn)的。
因此对于堆排序,我们采用向下调整算法较优。
堆排序,大家可以参考我的这篇文章:堆排序
相关文章:
堆的实现——对的应用(堆排序)
文章目录 1.堆的实现2.堆的应用--堆排序 大家在学堆的时候,需要有二叉树的基础知识,大家可以看我的二叉树文章:二叉树 1.堆的实现 如果有⼀个关键码的集合 K {k0 , k1 , k2 , …,kn−1 } ,把它的所有元素按完全⼆叉树…...
新生讲课——图和并查集
1.图的存储 (1).邻接矩阵 邻接矩阵可以借助stl中的vector,我们通过开一个二维矩阵,g[u]中存储的是u可以到达的点,定义如下 const int N 2e5 10; vector<int> g[N] 若是遇到带权图则定义如下 const int N 2e5 10; vector <pair <int ,…...
基于深度学习的视觉检测小项目(十七) 用户管理后台的编程
完成了用户管理功能的阶段。下一阶段进入AI功能相关。所有的资源见文章链接。 补充完后台代码的用户管理界面代码: import sqlite3from PySide6.QtCore import Slot from PySide6.QtWidgets import QDialog, QMessageBoxfrom . import user_manage # 导入使用ui…...
实战:利用百度站长平台加速网站收录
本文转自:百万收录网 原文链接:https://www.baiwanshoulu.com/33.html 利用百度站长平台加速网站收录是一个实战性很强的过程,以下是一些具体的步骤和策略: 一、了解百度站长平台 百度站长平台是百度为网站管理员提供的一系列工…...
web-XSS-CTFHub
前言 在众多的CTF平台当中,作者认为CTFHub对于初学者来说,是入门平台的不二之选。CTFHub通过自己独特的技能树模块,可以帮助初学者来快速入门。具体请看官方介绍:CTFHub。 作者更新了CTFHub系列,希望小伙伴们多多支持…...
【C++】P1957 口算练习题
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目描述输入格式:输出格式: 💯我的做法代码实现: 💯老师的做法代码实现: 💯对比分析&am…...
第二十三章 MySQL锁之表锁
目录 一、概述 二、语法 三、特点 一、概述 表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。 对于表级锁,主要分为以下三类: 1. 表锁 2. 元数…...
linux 进程补充
环境变量 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如:我们在编写C/C代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪 里,但是照样可以链接成功&#…...
渗透测试之文件包含漏洞 超详细的文件包含漏洞文章
目录 说明 通常分为两种类型: 本地文件包含 典型的攻击方式1: 影响: 典型的攻击方式2: 包含路径解释: 日志包含漏洞: 操作原理 包含漏洞读取文件 文件包含漏洞远程代码执行漏洞: 远程文件包含…...
Java 大视界 -- Java 大数据在智能医疗影像诊断中的应用(72)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也期待你毫无保留地分享独特见解,愿我们于此携手成长,共赴新程!💖 一、…...
Web - CSS3浮动定位与背景样式
概述 这篇文章主要介绍了 CSS3 中的浮动定位、背景样式、变形效果等内容。包括 BFC 规范与创建方法、浮动的功能与使用要点、定位的多种方式及特点、边框与圆角的设置、背景的颜色、图片等属性、多种变形效果及 3D 旋转等,还提到了浏览器私有前缀。 BFC规范与浏览…...
ConcurrentHashMap线程安全:分段锁 到 synchronized + CAS
专栏系列文章地址:https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标: 理解ConcurrentHashMap为什么线程安全;ConcurrentHashMap的具体细节还需要进一步研究 目录 ConcurrentHashMap介绍JDK7的分段锁实现JDK8的synchr…...
系统学习算法:专题九 穷举vs暴搜vs深搜vs回溯vs剪枝
其中标题的深搜,回溯,剪枝我们之前专题都已经有过学习和了解,这里多了两个穷举和暴搜,其实意思都差不多,穷举就是穷尽力气将所有情况都列举出来,暴搜就是暴力地去一个一个情况搜索,所以就是全部…...
解决 Pandas DataFrame 索引错误:KeyError:0
在使用 Pandas 处理数据时,KeyError 是一个常见的问题,尤其是在尝试通过索引访问数据时。本文将通过一个实际案例(使用SKLearn中的MINIST数据集为例),详细分析 KeyError 的原因,并提供解决方法。 1 问题背…...
deepseek的对话风格
概述 deepseek的对话风格,比一般的模型的回答多了思考过程,这是它比较可爱的地方,模型的回答有了思考过程,对用户而言大模型的回答不完全是一个黑盒。 deepseek的对话风格 train_prompt_style """Below is an…...
制造业设备状态监控与生产优化实战:基于SQL的序列分析与状态机建模
目录 1. 背景与挑战 2. 数据建模与采集 2.1 数据表设计 设备状态表(记录设备实时状态变更)...
Javaweb学习之Mysql(Day5)
(一)Mysql概述 (1)MYSQL通用语法 SQL语句可以单行或多行书写,以分号结尾。 SQL语句可以使用空格/缩进来增强语句的可读性(即,空格和缩进不影响代码的执行)。 MySQL数据库的SQL语句不区分大小写。 注释: 1. 单行注释: -- 注释内容 或 # 注释内容 (MySQL 特有 …...
C++ Primer 迭代器
欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...
Java的String与StringBuilder例题
package com.jiachen.StringBuilderDemo1;import java.util.Scanner;public class Exercise2 {public static void main(String[] args) {Scanner scanner new Scanner(System.in);String s scanner.nextLine().trim(); // 读取输入并去除前后空格String result;// 根据…...
Vue.js 如何选择合适的组件库
Vue.js 如何选择合适的组件库 大家在开发 Vue.js 项目的时候,都会面临一个问题:我该选择哪个组件库? 市面上有很多优秀的 Vue 组件库,比如 Element Plus、Vuetify、Quasar 等,它们各有特点。选择合适的组件库…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

