一篇文章讲透排序算法之堆排序

1.前言 

在学习这篇文章之前,请大家先学习堆这一数据结构中堆的概念,向下调整算法,向下调整建堆

有关堆的实现方式请参考:堆的实现

堆排序就是利用堆里面学习过的知识点进行排序,如何进行排序呢?

2.堆排序原理剖析

现在我们要对一个无序的数组升序排列,那么我们应该利用大堆还是小堆进行排序呢?

这时我们大家就会想,既然是升序排列,那么我们建一个小堆不就可以了吗,刚好小堆的第一个元素是最小的元素。

  • 建小堆可行性分析

好,那么我们现在来思考一下这种方法的可行性。

现在我们给出如下一个小堆。

现在我们可以确保根节点是最小的了,下面我就就要从第二层选最小的数了,这里我们选到了右子树2,但是根结点的左右两棵子树之间是没有联系的,我们应该如何判决左子树8和右子树2的子树们的关系呢?这时就需要我们遍历才能确定大小关系了,而后续的每一次比较都需要这么一个过程。时间复杂度就变的相当高了。若如此建堆,堆排序就是一个理解起来困难而时间复杂度又高的离谱的排序方法了

  • 建大堆可行性分析

既然建小堆不可以,那么,建大堆应该如何排序呢?又有没有优势呢?

首先,我们可以确定的一点是,大堆的堆顶一定是一整个堆中最大的元素。

但是我们排的是升序,最大的一个应该在堆的最后面才对,那么我们直接交换堆顶元素和堆尾元素的位置不就可以让堆的最后一个元素是最大的了嘛

这时,新的问题是,我们的交换破坏了堆原来的结构,那么这时我们需要做的工作则是恢复堆原来的结构。这不就是我们的向下调整算法所能做的事嘛,因此我们每次交换了之后用一个向下调整算法即可。

3.堆排序代码详细阐述

我们首先完成第一次交换和向下调整:

int end=n-1;//n是数组长度
swap(&arr[0], &arr[end]);
AdjustDown(a, end, 0);

下面我们要做的事情即将数组内所有的元素都按照这种方式进行排序,这就需要我们将上述代码嵌套进一个循环内,而由于此时最后一个元素已经是最大的了,因此我们需要剔除掉这个元素,在这里我们直接让end-1即可。

while (end>0)
{swap(&arr[0], &arr[end]);AdjustDown(a, end, 0);end--;
}

上述代码即可完成一次堆排序。

而由于我们传进来的数组的元素是无序的,因此我们首先需要将其调整为堆,之后再进行上述操作即可完成堆排序。

void AdjustDown(HPDataType * a, int n, int parent)
{// 先假设左孩子大int child = parent * 2 + 1;while (child < n)// 当child>=n时就说明child已经到达叶子节点了{// 先找出左右孩子节点中大的那个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{break;}}
}
void HeapSort(int* a, int n)
{// 降序,建小堆// 升序,建大堆for (int parent = (n - 1 - 1) / 2; parent > 0; parent--){AdjustDown(a, n, parent);}int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}

4.堆排序时间复杂度分析

初始化堆的时间复杂度为O(n)
n-1次删除操作的时间复杂度为O(nlogn)
所以总操作时间复杂度为O(nlogn)

由于每删除一个元素,总元素减一。
共有n-1次删除操作,操作时间应该为log(n)+log(n-1)+…+log(3)+log(2) = log(n!)。
又由于(n/2)^(n/2) ≤ n!≤ n ^ n,即 1/4*nlog(n) ≤ n! ≤ nlogn。常数可舍去,时间复杂度为O(nlogn)

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

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

相关文章

2.4 Makefile中使用变量

Variables Make Makefiles Simpler 一、本节概要 Variables Make Makefiles Simpler &#xff08;变量使Makefile更简单&#xff09;&#xff0c;以下是官方给出的原文&#xff0c;接下来会对本节内容进行拆解&#xff0c;并给出详细示例代码。 In our example, we had to l…

这方法真牛B!论文降重从81%直降1.9%

目录 一、万字论文&#xff0c;从0到1&#xff0c;只需1小时二、获取途径三、论文从81&#xff05;降到1.9&#xff05;四、内容是别人的&#xff0c;话是自己的五、AI工具 --> 中文论文降重六、论文降重小技巧 一、万字论文&#xff0c;从0到1&#xff0c;只需1小时 通过O…

Python-3.12.0文档解读-内置函数map()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 详细说明 map(function, iterable, *iterables) 参数 返回值 示例 注意事项 参考…

Java练习1

题目要求 有一个交通工具接口类Vehicles&#xff0c;有work接口有Horse类和Boat类分别实现Vehicles创建交通工具工厂类&#xff0c;有两个方法分别获得交通工具Horse和Boat有Person类&#xff0c;有name和Vehicles属性&#xff0c;在构造器中为两个属性赋值实例化Person对象“…

如何让大模型更聪明?提升AI智能的关键策略

如何让大模型更聪明&#xff1f;提升AI智能的关键策略 &#x1f916; 如何让大模型更聪明&#xff1f;提升AI智能的关键策略摘要引言方向一&#xff1a;算法创新&#x1f680;1.1 自监督学习的崛起1.2 强化学习的应用 方向二&#xff1a;数据质量与多样性&#x1f4ca;2.1 数据…

大模型日报2024-05-26

大模型日报 2024-05-26 大模型资讯 AI助力揭示海洋和肠道中的病毒活动 摘要: 病毒在微生物生态系统中是神秘且难以理解的力量。研究人员发现&#xff0c;病毒可以感染、杀死并操控人类。AI技术有望帮助我们更好地了解这些病毒在海洋和肠道中的行为。 微软推出Windows Copilot R…

Spring:IoC容器(基于XML管理bean)

1. HelloWorld 三个步骤&#xff1a; 1.创建类 2.配置xml文件 3.通过xml文件使得bean实列化 1. 创建类 package com.itgyl.bean;public class HelloWorld {public HelloWorld() {System.out.println("1.通过无参构造创建对象");}public void hello() {System.out.p…

SpringCloud配置文件bootstrap不生效

解决方案&#xff1a; 情况一、SpringBoot 版本 小于 2.4.0 版本&#xff0c;添加以下依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-context</artifactId> </dependency> 情况二、SpringBoot…

乡村振兴的乡村公共服务提升:提升乡村公共服务水平,满足农民多样化需求,构建幸福美好的美丽乡村

目录 一、引言 二、乡村公共服务提升的必要性 &#xff08;一&#xff09;满足农民多样化需求 &#xff08;二&#xff09;促进乡村经济发展 &#xff08;三&#xff09;构建幸福美好的美丽乡村 三、乡村公共服务面临的挑战 &#xff08;一&#xff09;基础设施薄弱 &a…

粘土滤镜特效怎么弄?5个简易制作粘土软件一学就会

#是谁把夏天的氛围感拿捏了#&#xff0c;哦~原来是AI粘土特效。 这玩意儿最近在社交媒体上可是火得一塌糊涂&#xff0c;大家都在用它给自己的照片来个大变身&#xff0c;变成那种丑萌丑萌的粘土小人儿。 如果大家也想尝试一下&#xff0c;那就跟着我来看看几款超好用的粘土滤…

java处理中文脱敏

方法一&#xff0c;简单的&#xff0c;不计算文字长度去设置脱敏 public static String dataDesensitization1(String content){String regex "(.{2}).*(.{2})";return ReUtil.replaceAll(content, regex, matcher -> {try {if (CharSequenceUtil.isBlank(match…

基于Django框架的项目搭建后台首页

(1). 创建数据库 osdb 进入MySQL数据库中&#xff0c;创建一个数据库名为&#xff1a;osdb 通过数据表结构来创建数据表&#xff1a; -- 员工信息表 CREATE TABLE user (id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 员工账号id,username varchar(50) DEFAULT NULL C…

MySQL:图文超详细教程MySQL5.7下载与安装

一、前言 MySQL 5.7 是一个重要的数据库管理系统版本&#xff0c;它带来了多项改进和新特性&#xff0c;本文将超详细的带大家手动安装一下MySQL5.7。 二、下载MySQL5.7版本 MySQL5.7安装包 链接&#xff1a;https://pan.baidu.com/s/1lz5rp9PwfyeHzkEfI_lW6A 提取码&#…

图卷积神经网络的简史 及其与卷积神经网络的异同

图卷积神经网络&#xff08;GCN&#xff09;已经在处理图结构数据方面取得了巨大的成功。在本小节中&#xff0c;我们将深入探讨图卷积神经网络的起源、发展历程&#xff0c;并提供一个简单的Python代码实现示例&#xff0c;以帮助读者更好地理解这一概念。 图卷积神经网络的简…

Kubernetes 文档 / 概念 / 服务、负载均衡和联网

Kubernetes 文档 / 概念 / 服务、负载均衡和联网 此文档从 Kubernetes 官网摘录 中文地址 英文地址 Kubernetes 网络模型 集群中每一个 Pod 都会获得自己的、 独一无二的 IP 地址&#xff0c; 这就意味着你不需要显式地在 Pod 之间创建链接&#xff0c;你几乎不需要处理容器…

Django 请求方式

在 Django 中要想知道请求方式&#xff0c;可以在views.py文件里获知。views.py 是在自己创建的app文件夹里的 from django.shortcuts import redirectdef login(request):# 获取请求方式 GET/POSTprint(request.method)# 获取url中的参数&#xff1a;/login/?n1123&n2…

深入理解 Docker:概念、原理与操作指南

推荐一个AI网站&#xff0c;免费使用豆包AI模型&#xff0c;快去白嫖&#x1f449;海鲸AI Docker 简介、原理及操作 Docker 是一个开源的容器化平台&#xff0c;它可以将应用程序及其依赖项打包到一个可移植的容器中&#xff0c;从而实现应用程序的快速部署、运行和管理。本文…

c# 贪心算法(Greedy Algo)

贪婪是一种算法范式&#xff0c;它逐步构建解决方案&#xff0c;始终选择提供最明显和直接收益的下一个部分。贪婪算法用于解决优化问题。 如果问题具有以下属性&#xff0c;则可以使用贪心法解决优化问题&#xff1a; 每一步&#xff0c;我们都可以做出当前看来最好的选择&…

IDEA 2024.1安装与破解

一、下载 官网地址&#xff1a;https://www.jetbrains.com/idea/download/other.html 二、安装 傻瓜式安装即可 三、破解 3.1 破解程序 网站&#xff1a;https://3.jetbra.in/ 3.2 获取激活码 点击*号部分即可复制成功