十大排序之堆排序(详解)

news2024/12/25 2:02:41

文章目录

  • 🐒个人主页
  • 🏅算法思维框架
    • 📖前言:
  • 🎀堆排序 时间复杂度O(n*logn)
      • 🎇1. 算法步骤思想
      • 🎇2、动画演示
      • 🎇3.代码实现

🐒个人主页

🏅算法思维框架

📖前言:

本篇博客主要以介绍十大排序算法中的堆排序,有详细的图解、动画演示、良好的代码注释,帮助加深对这些算法的理解,进行查漏补缺~

🎀堆排序 时间复杂度O(n*logn)

堆排序(Heapsort) 是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列; 堆排序的平均时间复杂度为 Ο(nlogn)。

有好多人都说堆排序代码有点复杂但是它的思路其实是最好理解的!他的思路是将大根堆顶的最大值元素放到数组没有排序区间的末尾,然后对没有排序的区间重新变成大根堆,直到没有排序的区间中只剩一个元素,就排好序了。
难的无非是不会将一个数组变成堆heapify,也不会取出堆顶元素后(删除操作(下沉操作)),再将其变成堆
堆排序详细图解

🎇1. 算法步骤思想

  1. 创建一个堆 H[0……n-1] ;【heapify()操作----->时间复杂度O(n)】
  2. 把堆首(最大值)和堆尾互换;【交换数组中的堆顶与数组未排序区间的末尾元素】
  3. 调用swim()方法----->时间复杂度O(logn),使除过堆尾元素的树满足最大堆的性质;【对没有排序的区间进行下沉操作,重新生成堆】
  4. 重复步骤 2,直到堆中只有一个元素。

🎇2、动画演示

在这里插入图片描述
在这里插入图片描述

🎇3.代码实现

public int[] sort(int[] nums) {
        if(nums==null||nums.length<2){
            return nums;
        }
        //思路:【堆排序】:先将nums[]构建成大根堆heapify()操作,
        // 再将堆顶元素与未排序区间的末尾元素进行交换,对此时的堆顶元素进行【无序区间】的下沉操作,重复上述操作....直至数组有序
        heapify(nums);//【将nums[]数组变成堆】
        //进行排序
        for (int i = nums.length-1; i >0; i--) {
            //交换
            int temp=nums[i];
            nums[i]=nums[0];
            nums[0]=temp;
            //对根节点进下沉操作,让没有排序的区间重新变成堆
            swim(nums,0,i);
        }
        return nums;
    }
    //写两个辅助方法:获取父亲节点下标,获取左孩子节点下标
    private int getParentIndex(int childIndex){
        return (childIndex-1)/2;
    }
    private int getLeftChildIndex(int parentIndex){
        return 2*parentIndex+1;
    }
    private void heapify(int[] nums){//【将nums[]数组变成堆】
        //思路:拿到数组最后一个元素的父亲节点下标,直到根节点,依次进行下沉操作
        int lastParentIndex=getParentIndex(nums.length-1);
        for (int i = lastParentIndex; i >=0 ; i--) {
            swim(nums,i,nums.length);
        }
    }

    /**
     * 下沉操作
     * @param nums 进行下沉操作的数组
     * @param index  需要进行下沉操作的节点
     * @param length 进行下沉操作的区间长度
     */
    private void swim(int[] nums,int index,int length){
        //下沉思路:将目标值rootVal与当前节点index的左右孩子最大优先级进行比较:
        // 1.如果rootVal<孩子优先级,孩子优先级覆盖当前父亲节点index,index索引最大优先级的孩子,重新找孩子进行比较
        // 2.如果rootVal>=孩子优先级,找到了break,将当前节点nums[index]=rootVal
        //3.如果找到头都没有找到,将当前节点nums[index]=rootVal            【情况2、3可合并处理】
        int rootVal=nums[index];//寄存将要下沉节点的值
        int leftIndex=getLeftChildIndex(index);//获取当前节点的左孩子
        int maxChildPiroirtyIndex=leftIndex;//【默认左孩子为孩子的最大优先级,原因堆是一棵完全二叉树...】
        while (leftIndex<length){//左孩子存在
            int rightIndex=leftIndex+1;//右孩子下标
            if(rightIndex<length&&nums[leftIndex]<nums[rightIndex]){//左孩子存在且左孩子优先级<右孩子优先级
                maxChildPiroirtyIndex=rightIndex;
            }
            //进行优先级的比较
            if(rootVal<nums[maxChildPiroirtyIndex]){
                nums[index]=nums[maxChildPiroirtyIndex];//覆盖父节点
                //更新索引指向
                index=maxChildPiroirtyIndex;
                leftIndex=getLeftChildIndex(index);
                maxChildPiroirtyIndex=leftIndex;
            }else {
                break;
            }
        }
        nums[index]=rootVal;//插入目标值
    }

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

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

相关文章

Redis集群(新)

1.什么是集群 Redis集群实现了对Redis的水平扩容&#xff0c;可实现并发写操作&#xff0c;启动n个redis节点&#xff0c;将数据分别存储在不同的节点中&#xff0c;每块节点负责不同区域的插槽&#xff0c;所以Redis集群通过分区来提供一定程度的可用性。 Redis集群现采用的是…

mac测试远程端口是否可连接

打开命令行工具&#xff0c;使用命令nc -z ip port即可 &#xff0c;如果成功&#xff0c;则会返回如下信息&#xff1a; 。

算法基础之表达式求值

算法基础之表达式求值 中序表达式求值 用栈 将字符和数字分别用栈存储 由下往上计算 左子树算完再算右子树 判断方法&#xff1a;当前符号优先级<前一个符号优先级 则左右子树已遍历完 #include<iostream>#include<cstring>#include<stack>#include&l…

单文件组件MVVM

单文件组件&MVVM 所谓组件化开发&#xff0c;就是创建一个个组件。 Vue是一个大类&#xff0c;渲染一切从new Vue开始。 指定视图&#xff1a;el template render:jsx语法 $mount[数学公式] 编译App.vue&#xff0c;作为视图入口 单个组件&#xff1a;结构 样式 data compu…

彩纸屋在线少儿编程源码/scratch在线编程系统/培训管理系统源码/在线培训系统源码PHP

源码简介&#xff1a; 彩纸屋在线少儿编程源码&#xff0c;它是scratch在线编程系统&#xff0c;作为培训管理系统源码/在线培训系统源码&#xff0c;采用PHP源码。 彩纸屋是全国首家提供scratch开源定制和少儿编程培训管理系统源代码的服务商&#xff0c;彩纸屋提供的scratc…

MIT6.824-Raft笔记:Raft初探、副本间log时序

从宏观角度说明raft在程序中的作用&#xff0c;和客户端的关系&#xff0c;以及多个副本之间的关系&#xff1b;从微观角度说明多个副本之间raft对日志处理的流程。 1. Raft 初探 宏观角度说明raft在程序中的作用&#xff0c;和客户端的关系&#xff0c;以及多个副本之间的关…

激活函数与非线性化:探索神经网络中的关键元素

随着人工智能领域的迅猛发展&#xff0c;神经网络成为实现各种复杂任务的有力工具。其中&#xff0c;激活函数及其非线性化特性扮演着至关重要的角色。本文将深入探讨激活函数的基本概念、作用原理以及常见的几种激活函数&#xff0c;并介绍它们在神经网络中发挥的重要作用。 …

Web3 进入“殖民时代”

最近在 AI 和 Web3 领域发生了两件“大”事&#xff0c;两件事都具有指标意义&#xff0c;但在媒体上其意义都被大量的八卦细节给掩埋了。 其实看待任何重大事件&#xff0c;都可以有两种不同的视角。第一是娱乐的视角&#xff0c;在新闻事件中找乐子。如果是本着这个目的&…

STM32-使用固件库新建工程

参考链接: 【入门篇】11-新建工程—固件库版本&#xff08;初学者必须认认真真看&#xff09;_哔哩哔哩_bilibili 使用的MCU是STM32F103ZET6 。 这篇参考的是野火的资料&#xff0c;可以在“野火大学堂”或者它的论坛上下载。&#xff08;我通常是野火和正点原子的资料混着看的…

【DDS】OpenDDS配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍OpenDDS配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更…

能让PDF看起来像是扫描件的Look Scanned

什么是 Look Scanned ? Look Scanned 是一个能够让 PDF 看起来就像是扫描件一样的纯前端网站。你再也不需要麻烦地打印之后扫描了&#xff0c;你所需要的就是鼠标点几下。 这是个挺有意思的软件&#xff0c;但是老苏不确定什么场景下会用到这个软件&#xff0c;如果不想自己搭…

89. 打家劫舍【动态规划】

题目 题解 class Solution:def rob(self, nums: List[int]) -> int:N len(nums)# 定义状态: dp[i]表示从第i间房子开始抢劫&#xff0c;最多能抢到的金额dp [0 for i in range(N)]for i in range(N-1, -1, -1):if i N-1:dp[i] nums[i]elif i N-2:dp[i] max(nums[i], …

C语言—一维数组在内存中的存放

1、先看代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int arr[]{1,2,3,4,5,6,7,8,9,10}; int szsizeof(arr)/sizeof(arr[0]);int i0;for(i0;i<sz;i){printf("&arr[%d] %p\n",i,&arr[i]);}return 0; } 2、定…

【Mybatis】Mybatis操作数据库详解

Mybatis操作数据库 什么是MybatisMybatis入门准备工作创建Springboot工程 建表 创建实体类 配置数据库连接字符串编写持久层代码单元测试 Mybatis的基础操作打印日志参数传递增(insert)返回主键 删(delete)改(update)查(select) Mybatis XML配置文件配置连接字符串和Mybatis写持…

Jenkins CI/CD

1、 Jenkins CI/CD 流程图 说明&#xff1a;这张图稍微更形象一点&#xff0c;上线之前先把代码git到版本仓库&#xff0c;然后通过Jenkins 如Java项目通过maven去构建&#xff0c;这是在非容器之前&#xff0c;典型的自动化的一个版本上线流程。那它有哪些问题呢&#xff1f; …

Docker Swarm总结+基础、集群搭建维护、安全以及集群容灾(1/3)

博主介绍&#xff1a;Java领域优质创作者,博客之星城市赛道TOP20、专注于前端流行技术框架、Java后端技术领域、项目实战运维以及GIS地理信息领域。 &#x1f345;文末获取源码下载地址&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb;…

基于C#实现外排序

一、N 路归并排序 1.1、概序 我们知道算法中有一种叫做分治思想&#xff0c;一个大问题我们可以采取分而治之&#xff0c;各个突破&#xff0c;当子问题解决了&#xff0c;大问题也就 KO 了&#xff0c;还有一点我们知道内排序的归并排序是采用二路归并的&#xff0c;因为分治…

【Redis基础】Redis安装及管理详细教程

✅作者简介&#xff1a;大家好&#xff0c;我是小杨 &#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; 1&#xff0c;UBuntu安装Redis 1&#xff0c;使用su命令切换到root用户 su2&#xff0c;使用se…

windows运行Pangolin应用填坑心得——如何在window应用轻量级opengl软件Pangolin库显示3D界面及窗口

目录 0、前言1、最有效的安装打开方式准备工作安装git安装vcpkg&#xff08;1&#xff09;下载&#xff08;2&#xff09;安装&#xff08;3&#xff09;集成至vs 安装cmake 安装pangolin 2、应用实例c工程&#xff08;1&#xff09;vs创建新工程&#xff08;2&#xff09;新工…

盘点60个Python爬虫源码Python爱好者不容错过

盘点60个Python爬虫源码Python爱好者不容错过 爬虫&#xff08;Spider&#xff09; 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1JWrDgl46_ammprQaJiKqaQ?pwd8888 提取码&#xff…