【数据结构】堆的创建

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

  • 一、基于大堆的上下调整
    • 1.向上调整
      • (1)解决措施:
      • (2)代码实现
      • (3)测试
    • 2.向下调整
      • (1)解决措施:
      • (2)代码实现
    • 3.总结
  • 二、创建堆
    • 建堆【方法一】使用向上调整
      • 1.思路
      • 2.代码实现
    • 建堆【方法二】使用向下调整
      • 1.思路:
  • 三、堆排序
    • 🌸排升序【方法一:向上】
      • 1.思路:
      • 2.代码实现:
      • 3.时间复杂度分析
    • 🌱排降序
      • 1.思路:
      • 2.代码实现:
      • 3.时间复杂度分析

前言:

在上一篇博客中,主要讲到了关于堆的各种操作。那么本篇博客将会讲讲我们通过堆可以实现的一些作用-----如堆排序

一、基于大堆的上下调整

上一篇博客中的上下调整,都是以调成小堆为目标。那怎样才能实现调成大堆呢?🌸

1.向上调整

(1)解决措施:

只需要修改比较符>;改为a[parent]<a[child],即可

(2)代码实现

//向上调整
void AdjustUp(HPDataType* a, int child)
{//传入数组,child为孩子节点下标int parent = (child - 1) / 2;//当一直交换到根,停止while (child>0){if (a[parent] < a[child]){Swap(&a[parent], &a[child]);child = parent;parent = (child - 1) / 2;}elsereturn;}
}

(3)测试

输入数组:int a[] = { 2,4,5,3,1,9 };
在这里插入图片描述

2.向下调整

(1)解决措施:

只需要修改比较符 <改为child + 1 < n && a[child + 1] > a[child],
因为建大堆,需要找大的那个进行交换。

(2)代码实现

//向下调整
void AdjustDown(HPDataType* a, int n, int parent)
{int child = parent * 2 + 1;//一直交换到数的最后,也就是数组的最后一个位置while (parent<n){if (child + 1 < n && a[child + 1] < a[child]){child++;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);// 继续往下调整parent = child;child = parent * 2 + 1;}else{return;}}
}

3.总结

-大堆小堆
向上调整parent>childparent<child
向下调整比较两个孩子,选择的进行比较交换选择的进行比较交换

二、创建堆

两种方法建堆均以建立小堆为目标。无论是创建小堆还是创建大堆,思路都一样,通过修改Adjust方法即可

建堆【方法一】使用向上调整

创建堆的思路可以通过向上调整,也可通过向下调整。这里讲通过向上调整建立堆.<从上到下>

由于我的AdjustUp函数是用来调整大堆的,所以,这里创建的也是大堆。

1.思路

传入参数
a:数组,n:是数组元素个数
1.为p->a开辟n个空间;
2.利用memcpy函数,把数组a复制到p->a中
3.在使用AdjustUp调整,从1-n-1逐步向下延伸;
在这里插入图片描述
在这里插入图片描述

2.代码实现

//建立大堆
void HeapInitArray(HP* p, int* a, int n)
{//a:数组,n:是数组元素个数assert(p);assert(a);p->a = (HPDataType*)malloc(sizeof(HPDataType) * n);if (p->a == NULL){perror("malloc fail");exit(-1);}p->size = n;p->capacity = n;//把传入数组a复制到p->a中memcpy(p->a, a, sizeof(HPDataType) * n);// 向上调整,调整成一个小堆for (int i = 1; i < n; i++){AdjustUp(p->a, i);}
}

建堆【方法二】使用向下调整

这里通过向下调整建立堆.<从下到上>

1.思路:

1.从倒数第一个非叶子节点开始向下调整,因为叶子节点没有左右子树。
2.根据Adjust方法,比较交换。
3.层层向上,下层可以保证是堆。从而可保证向下调整的进行。
所以,我们说这种调整方式是从下到上的。
步骤图
在这里插入图片描述
在这里插入图片描述

三、堆排序

🌸排升序【方法一:向上】

口诀:排升序,建大堆

意思是:想要将数组的顺序变成一个升序的,那么可以建立一个大堆存在数组中,在对堆进行调整。即可将数组变成一个升序数组。

1.思路:

首先建立大堆;
1.堆顶与最后一个节点交换,由于是大堆,堆顶是最大值。交换后,就选出了最大值并将其放到数组的组后位置
2.并将堆的长度减1(数组长度减1)。
3.在对剩下的堆进行向下调整从而将第二大的数调整到了堆顶。此步骤时间复杂度:O(logN)
4.最后,这个原本存储大堆的数组,就变成了一个从小到大的升序数组

2.代码实现:

//排升序
void HeapSortASC(int* a, int n)
{//建立大堆for (int i = 1; i < n; i++){AdjustUp(a, i);}int end = n - 1;while (end > 0){swap(&a[0], &a[end]);//每次调整从根0到end,end每次会减1。AdjustDown(a, end, 0);end--;}
}

3.时间复杂度分析

一次AdjustUp调整的时间复杂度是O(logN)
一共执行n-1次,所以,时间复杂度一共是O(N*logN)。

🌱排降序

口诀:排降序,建小堆

1.思路:

首先建立小堆;
1.堆顶与最后一个节点交换,由于是小堆,堆顶是最小值。交换后,就选出了最小值并将其放到数组的组后位置,
2.并将堆的长度减1(数组长度减1)。
3.在对剩下的堆进行向下调整从而将第二大的数调整到了堆顶。此步骤时间复杂度:O(logN)
4.最后,这个原本存储大堆的数组,就变成了一个从小到大的升序数组

2.代码实现:

修改AdjustUp(a, i);和AdjustDown(a, end, 0);为调小堆

void HeapSortDES(int* a, int n)
{//建立小堆for (int i = 1; i < n; i++){AdjustUp(a, i);}int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);//每次调整从根0到end,end每次会减1。AdjustDown(a, end, 0);--end;}
}

3.时间复杂度分析

一次AdjustUp调整的时间复杂度是O(logN)
一共执行n-1次,所以,时间复杂度一共是O(N*logN)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/107920.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jmeter采集ELK平台海量业务日志( 采用Scroll)

由于性能测试需要&#xff0c;需采集某业务系统海量日志&#xff08;百万以上&#xff09;来使用。但Elasticsearch的结果分页size单次最大为10000&#xff08;运维同事为保证ES安全&#xff09;。为了能够快速采集ELK平台业务日志&#xff0c;可以使用以下2种方式采集&#xf…

spring spring-boot spring-cloud spring-cloud-alibaba之间版本对应关系

spring 版本与 jdk 的对应关系 https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions 从 spring 6.0 开始使用 jdk 17 进行编译 对应的相关 servlet 容器&#xff08;tomcat、undertow、jetty等&#xff09;的 servlet 规范转移到 eclipse&…

线程安全问题(3)--- wait(),notify()

前言 在多线程的环境下&#xff0c;我们常常要协调多个线程之间的执行顺序&#xff0c;而为了实现这一点&#xff0c;Java提供了一些方法来帮助我们完成这一点。 一&#xff0c;wait() 作用&#xff1a; 使当前线程进入等待状态 释放当前的锁 (即该方法必须和 synchrnized 关键…

【C++】泛型编程 | 函数模板 | 类模板

一、泛型编程 泛型编程是啥&#xff1f; 编写一种一般化的、可通用的算法出来&#xff0c;是代码复用的一种手段。 类似写一个模板出来&#xff0c;不同的情况&#xff0c;我们都可以往这个模板上去套。 举个例子&#xff1a; void Swap(int& a, int& b) {int tmp …

Vue3 监听属性-watch

文章目录 Vue3 监听属性-watch1. 概念2. 实例2.1 通过使用 watch 实现计数器2.2 千米与米之间的换算2.3 异步加载中使用 watch2.4 小计 Vue3 监听属性-watch 1. 概念 Vue3 监听属性 watch&#xff0c;可以通过 watch 来响应数据的变化。 watch 的作用&#xff1a;用于监测响应…

想挑战你的智商?快来试试Java版灯谜猜猜乐!

前言 中秋佳节&#xff0c;是我国传统的重大节日之一。全国各地为了增强过节的气氛&#xff0c;都有许多传统的中秋活动&#xff0c;比如吃月饼、赏月、猜灯谜等等。其中&#xff0c;猜灯谜就是一项极具娱乐性的活动&#xff0c;它不仅可以增进亲友之间的感情&#xff0c;更重要…

C++数据结构AVL树

AVL树 &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;C &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容介绍数据结构中的avl树 文章目录 AVL树AVL树Ⅰ.avl树…

xxl-job2.1.2集成postgresql

admin模块改造 引入依赖 xxl-job-adminmodule中引入一下依赖 <!-- 引入数据源 与数据库 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.12</version></dependency><d…

数字藏品系统都有哪些功能?

数字藏品系统是用于管理和展示数字化文物、艺术品、历史资料和其他文化遗产的软件系统。这些系统通常具有以下一些功能&#xff1a; 数字资产管理&#xff1a;管理和组织数字化的文物、艺术品、档案和历史文献。这包括存储、索引和检索数字资产的能力。 多媒体支持&#xff1a…

[学习笔记]Node2Vec图神经网络论文精读

参考资料&#xff1a;https://www.bilibili.com/video/BV1BS4y1E7tf/?p12&spm_id_frompageDriver Node2vec简述 DeepWalk的缺点 用完全随机游走&#xff0c;训练节点嵌入向量&#xff0c;仅能反应相邻节点的社群相似信息&#xff0c;无法反映节点的功能角色相似信息。 …

【java】【SSM框架系列】【一】Spring

目录 一、简介 1.1 为什么学 1.2 学什么 1.3 怎么学 1.4 初识Spring 1.5 Spring发展史 1.6 Spring Framework系统架构图 1.7 Spring Framework学习线路 二、核心概念&#xff08;IoC/DI&#xff0c;IoC容器&#xff0c;Bean&#xff09; 2.1 概念 2.2 IoC入门案例 …

2.4.3 【MySQL】设置系统变量

2.4.3.1 通过启动选项设置 大部分的系统变量都可以通过启动服务器时传送启动选项的方式来进行设置。如何填写启动选项就是下面两种方式&#xff1a; 通过命令行添加启动选项。 在启动服务器程序时用这个命令&#xff1a; mysqld --default-storage-engineMyISAM --max-conn…