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

数据结构:堆

堆的概念

1.堆是一个完全二叉树

2.小堆(任何一个父亲<=孩子),大堆(任何一个父亲>=孩子)

堆的结构

物理结构:数组

逻辑结构:二叉树

#pragma once
#include<assert.h>
#include<iostream>
typedef int HPDataType;
typedef struct Heap
{HPDataType* _a;int _size;int _capacity;
}Heap;// 堆的构建
void HeapInit(Heap* hp);
void HeapInitArray(Heap* hp, HPDataType* a, int n);
// 堆的销毁
void HeapDestory(Heap* hp);
// 堆的插入
void HeapPush(Heap* hp, HPDataType x);
// 堆的删除
void HeapPop(Heap* hp);
// 取堆顶的数据
HPDataType HeapTop(Heap* hp);
// 堆的数据个数
int HeapSize(Heap* hp);
// 堆的判空
bool HeapEmpty(Heap* hp);
#include"标头.h"
void HeapInit(Heap* hp)
{assert(hp);hp->_a = NULL;hp->_capacity = 0;hp->_size = 0;
}void HeapInitArray(Heap* hp, HPDataType* a, int n)// 一次性初始化堆,插入所有值
{assert(hp);hp->_a = (HPDataType*)malloc(sizeof(HPDataType) * n);memcpy(hp->_a, a, sizeof(HPDataType) * n);
//第一个节点不用调,时间复杂度为O(n*logn)//for (int i = 1; i < n; i++)//向上调整建堆//{//	AdjustUp(hp->_a, i);//}
//叶节点不用调(没有子节点),时间复杂度为O(N)for (int i = (hp->_size-1 - 1) / 2; i >= 0; i--)//向下调整建堆//(hp->_size-1 - 1) / 2第一个-1是下标,后面的-1和/2是求父节点的公式{AdjustDown(hp->_a, hp->_size, i);}
}void HeapDestory(Heap* hp)
{assert(hp);free(hp->_a);hp->_a = NULL;hp->_capacity = 0;hp->_size = 0;
}void Swap(HPDataType* px, HPDataType* py)
{HPDataType temp = *px;*px = *py;*py = temp;
}
void AdjustUp(HPDataType* a, int child)//向上调整数据,是它成小堆/大堆
{int parent = (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void HeapPush(Heap* hp, HPDataType x)
{assert(hp);if (hp->_size == hp->_capacity){size_t newcapacity = hp->_capacity == 0 ? 4 : hp->_capacity * 2;HPDataType* temp = (HPDataType*)realloc(hp->_a, sizeof(HPDataType) * newcapacity);if (temp == NULL){perror("realloc fail");return;}hp->_a = temp;hp->_capacity = newcapacity;}hp->_a[hp->_size] = x;hp->_size++;AdjustUp(hp->_a, hp->_size - 1);
}void AdjustDown(HPDataType* a, int n, int parent)
{int child = parent * 2 + 1;//假设法选出小的孩子while (child < n){if (a[child + 1] < a[child] && child + 1 < n){++child;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}void HeapPop(Heap* hp)//删除堆顶的数据
{assert(hp);assert(hp->_size > 0);//不可以挪动覆盖来删除堆顶数据//问题1.挪动覆盖时间复杂度O(N)//    2.堆结构被破坏,父子变兄弟,兄弟变父子//因此可以将首尾数据交换,删除尾部数据,然后进行向下调整算法Swap(&hp->_a[0], &hp->_a[hp->_size - 1]);hp->_size--;AdjustDown(hp->_a, hp->_size, 0);
}HPDataType HeapTop(Heap* hp)
{assert(hp);return hp->_a[0];
}int HeapSize(Heap* hp)
{assert(hp);return hp->_size;
}bool HeapEmpty(Heap* hp)
{assert(hp);return hp->_size == 0;
}

堆排序

堆排序的本质是利用堆的性质,取出堆顶的数(最大或最小),然后将堆顶换成第二小/大的数

void HpSort(HPDataType* a, int n)
{Heap hp;HeapInitArray(&hp, a, n);int i = 0;while (!HeapEmpty(&hp)){a[i++] = HeapTop(&hp);HeapPop(&hp);}HeapDestory(&hp);
}

当然,这样的排序存在一定的缺点:

1.空间复杂度为O(N),太大了

2.使用是需要有堆这个数据结构

为了节省空间,可以通过将原数组改造成堆来排序,

排列出升序的数组采取堆排序应当使用大堆,因为小堆的堆顶是最小的数,堆顶的数已经是最小的了,不能改了

因此需要其他的数重新组成一个新堆,但是原本的堆全部乱了,父子变兄弟等问题会出现,只能重新建堆,浪费了时间因此需要采用大堆

大堆的堆顶是最大的,因此可以进行首尾交换,最大值就在数组尾部了,然后不把最后一个数看作堆内的数,继续进行向下调整,就可以选出次大的数


//创建大堆的向下调整
void AdjustDown(HPDataType* a, int n, int parent)
{int child = parent * 2 + 1;//假设法选出小的孩子while (child < n){if (a[child + 1] > a[child] && child + 1 < n){++child;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}void HpSort(HPDataType* a, int n)
{//先将数组建堆,时间复杂度O(N)for (int i = (n - 1 - 1) / 2; i >= 0; --i)//调整叶子上一层(叶子(最后面)在最后,不需要调整){AdjustDown(a, n, i);}//int end = n - 1;//end为数组下标while (end > 0){Swap(&a[0], &a[end]);//交换首尾AdjustDown(a, end, 0);//将堆首下调--end;}
}int main()
{int a[9] = { 9,8,7,6,5,4,3,2,1 };HeapSort(a, 9);for (int i = 0; i < 9; i++){printf("%d ", a[i]);}return 0;
}

这样,一个简单的堆排序就完成了

相关文章:

数据结构:堆

堆的概念 1.堆是一个完全二叉树 2.小堆(任何一个父亲<孩子),大堆(任何一个父亲>孩子) 堆的结构 物理结构:数组 逻辑结构:二叉树 #pragma once #include<assert.h> #include<iostream> typedef int HPDataType; typedef struct Heap {HPDataType* _a;int…...

CSS中三栏布局的实现

三栏布局一般指的是页面中一共有三栏&#xff0c;左右两栏宽度固定&#xff0c;中间自适应的布局&#xff0c;三栏布局的具体实现&#xff1a; 利用绝对定位&#xff0c;左右两栏设置为绝对定位&#xff0c;中间设置对应方向大小的margin的值。 .outer {position: relative;h…...

Linux搭建我的世界(MC)整合包服务器,All the Mods 9(ATM9)整合包开服教程

Linux使用MCSM面板搭建我的世界(Minecraft)整合包服务器&#xff0c;MC开服教程&#xff0c;All the Mods 9(ATM9)整合包搭建服务器的教程。 本教程使用Docker来运行mc服&#xff0c;可以方便切换不同Java版本&#xff0c;方便安装多个mc服版本。 视频教程&#xff1a;https:…...

让数据在业务间高效流转,镜舟科技与NineData完成产品兼容互认

近日&#xff0c;镜舟科技与NineData完成产品兼容测试。在经过联合测试后&#xff0c;镜舟科技旗下产品与NineData云原生智能数据管理平台完全兼容&#xff0c;整体运行高效稳定。 镜舟科技致力于帮助中国企业构建卓越的数据分析系统&#xff0c;打造独具竞争力的“数据护城河”…...

2.1HTML5基本结构

HTML5实际上不算是一种编程语言&#xff0c;而是一种标记语言。HTML5文件是由一系列成对出现的元素标签嵌套组合而成&#xff0c;这些标签以<元素名>的形式出现&#xff0c;用于标记文本内容的含义。浏览器通过元素标签解析文本内容并将结果显示在网页上&#xff0c;而元…...

设置浏览器显示小于12px以下字体

问题 我们在项目开发过程中有时候会遇到设计师给的小于12px的字体&#xff0c;IE、火狐浏览器、移动端等小于12px的字号大小还是可以正常显示的&#xff0c;但是谷歌浏览器上显示字体最小为12px&#xff0c;css设置font-size&#xff1a;10px&#xff0c;运行代码显示结果仍然…...

web蓝桥杯真题:成语学习

代码&#xff1a; //TODO 点击文字后&#xff0c;在idiom从左到右第一个空的位置加上改文字 getSingleWord(val) {let index this.idiom.indexOf() //从左往右查询空字符串this.$set(this.idiom, index, val) //响应式更新 },// TODO 校验成语是否输入正确答案 confirm…...

外包干了5天,技术明显退步。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入南京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…...

Vue:自定义消息通知组件

一、效果描述 在JS中使用一个Message函数&#xff0c;弹出一个自定义的消息框。 效果体验&#xff1a;缓若江海凝清光 二、实现方式 1.新建一个消息组件 2.新建一个js文件&#xff0c;新建一个需要导出函数 3.在函数中新建一个Vue实例&#xff0c;并将消息组件挂载上去。…...

2023 收入最高的十大编程语言

本期共享的是 —— 地球上目前已知超过 200 种可用的编程语言&#xff0c;了解哪些语言在 2023 为开发者提供更高的薪水至关重要。 过去一年里&#xff0c;我分析了来自地球各地超过 1000 万个开发职位空缺&#xff0c;辅助我们了解市场&#xff0c;以及人气最高和收入最高的语…...

Github 2024-03-11 开源项目周报 Top15

根据Github Trendings的统计&#xff0c;本周(2024-03-11统计)共有15个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目4TypeScript项目3Jupyter Notebook项目3C#项目1HTML项目1CSS项目1Dart项目1Lua项目1Shell项目1Rust…...

【DAY10 软考中级备考笔记】数据结构 图

数据结构 图 3月11日 – 天气&#xff1a;晴 晚上无线网络突然不能用了&#xff0c;花费好久弄这个&#xff0c;耽误了一些时间 1. 图的定义 这里需要注意完全图的定义&#xff0c;以及完全图的边数 这里需要注意连通图和连通分量的概念。 2. 图的存储结构 图有两种存储结构&a…...

java-ssm-jsp基于java的餐厅点餐系统的设计与实现

java-ssm-jsp基于java的餐厅点餐系统的设计与实现 获取源码——》公主号&#xff1a;计算机专业毕设大全...

蓝桥杯(1):python排序

1 基础 1.1 输出 1.1.1 去掉输出的空格 print("Hello","World",123,sep"") print("hello",world,123,sep) print(hello,world,123) #输出结果 #HelloWorld123 #helloworld123 #hello world 123 1.1.2 以不同的方式结尾 print(&quo…...

SpringMVC请求、响应和拦截器的使用

SpringMVC请求 RequestMapping注解 RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系 RequestMapping注解可以作用在方法和类上 1. 作用在类上&#xff1a;第一级的访问目录 2. 作用在方法上&#xff1a;第二级的访问目录 3. 细节&#xff1a;路径可以不编写…...

基于springboot+layui仓库管理系统设计和实现

基于 java springbootlayui仓库管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取…...

【开源-土拨鼠充电系统】鸿蒙 HarmonyOS 4.0+微信小程序+云平台

本人自己开发的开源项目&#xff1a;土拨鼠充电系统 ✍GitHub开源项目地址&#x1f449;&#xff1a;https://github.com/cheinlu/groundhog-charging-system ✍Gitee开源项目地址&#x1f449;&#xff1a;https://gitee.com/cheinlu/groundhog-charging-system ✨踩坑不易&am…...

[抽象]工厂模式([Abstract] Factory)——创建型模式

[抽象]工厂模式——创建型模式 什么是抽象工厂&#xff1f; 抽象工厂模式是一种创建型设计模式&#xff0c;让你能够保证在客户端程序中创建一系列有依赖的对象组时&#xff0c;无需关心这些对象的类型。 具体来说&#xff1a; 对象的创建与使用分离&#xff1a; 抽象工厂模…...

QT网络编程之实现UDP广播发送和接收

推荐一个不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;内容全面&#xff0c;作为入门科普和学习提升都不错&#xff0c;分享一下给大家&#xff1a;前言https://www.captainbed.cn/ai 一.UDP通信 1.QT中实现UDP通信主要用到了以下类&#xff1a;QUdpSocket、QHost…...

SSL VPN基础原理

目录 SSL ---安全传输协议&#xff08;安全套接层&#xff09;---TLS ----传输层安全协议 SSL的工作原理 SSL会话建立的过程 ​编辑 数据传输过程中的封装示意图 无客户端认证的过程 有客户端认证的过程 SSL VPN的核心技术---虚拟网关技术 服务器验证的点&#xff1a; 资源…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...