堆的实现——对的应用(堆排序)
文章目录
- 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 等,它们各有特点。选择合适的组件库…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...

