排序算法之堆排序

ops/2024/10/25 10:27:45/

目录

  • 一、简介
  • 二、代码实现
  • 三、应用场景


一、简介

算法平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度排序方式稳定性
堆排序O( N N N log ⁡ 2 N \log_{2}N log2N))O( N N N log ⁡ 2 N \log_{2}N log2N))O( N N N log ⁡ 2 N \log_{2}N log2N))O(1)In-place不稳定

稳定:如果A原本在B前面,而A=B,排序之后A仍然在B的前面;
不稳定:如果A原本在B的前面,而A=B,排序之后A可能会出现在B的后面;
时间复杂度: 描述一个算法执行所耗费的时间;
空间复杂度:描述一个算法执行所需内存的大小;
n:数据规模;
k:“桶”的个数;
In-place:占用常数内存,不占用额外内存;
Out-place:占用额外内存。

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种算法>排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:

大顶堆:每个节点的值都大于或等于其子节点的值,在堆算法>排序算法中用于升序排列;
小顶堆:每个节点的值都小于或等于其子节点的值,在堆算法>排序算法中用于降序排列;

堆排序的平均时间复杂度为 Ο(nlogn)。

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

算法步驟:

  • 1.创建一个堆 H[0……n-1];
  • 2.把堆首(最大值)和堆尾互换;
  • 3.把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
  • 4.重复步骤2 ,直到堆的尺寸为 1。

二、代码实现

java">public class HeapSort {public static void main(String[] args) {int[] arr = {12, 11, 15, 50, 7, 65, 3, 99,0};System.out.println("---排序前:  " + Arrays.toString(arr));heapSort(arr);System.out.println("堆排序从小到大:  " + Arrays.toString(arr));heapSort2(arr);System.out.println("堆排序从大到小:  " + Arrays.toString(arr));}private static int heapLen;public static void heapSort(int[] arr) {heapLen = arr.length;for (int i = heapLen - 1; i >= 0; i--) {heapify(arr, i);}for (int i = heapLen - 1; i > 0; i--) {swap(arr, 0, heapLen - 1);heapLen--;heapify(arr, 0);}}private static void heapify(int[] arr, int idx) {int left = idx * 2 + 1, right = idx * 2 + 2, largest = idx;if (left < heapLen && arr[left] > arr[largest]) {largest = left;}if (right < heapLen && arr[right] > arr[largest]) {largest = right;}if (largest != idx) {swap(arr, largest, idx);heapify(arr, largest);}}private static void swap(int[] arr, int idx1, int idx2) {int tmp = arr[idx1];arr[idx1] = arr[idx2];arr[idx2] = tmp;}private static void heapSort2(int[] arr) {heapLen = arr.length;for (int i = heapLen - 1; i >= 0; i--) {heapify2(arr, i);}for (int i = heapLen - 1; i > 0; i--) {swap(arr, 0, heapLen - 1);heapLen--;heapify2(arr, 0);}}private static void heapify2(int[] arr, int idx) {int left = idx * 2 + 1, right = idx * 2 + 2, largest = idx;if (left < heapLen && arr[left] < arr[largest]) {largest = left;}if (right < heapLen && arr[right] < arr[largest]) {largest = right;}if (largest != idx) {swap(arr, largest, idx);heapify2(arr, largest);}}
}

在这里插入图片描述

三、应用场景

稳定性:
堆排序是不稳定的算法,它不满足稳定算法的定义。它在交换数据的时候,是比较父结点和子节点之间的数据,所以,即便是存在两个数值相等的兄弟节点,它们的相对顺序在排序也可能发生变化。

应用场景
堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况,适合超大数据量

  • 大数据量的排序:堆排序适用于大数据量的排序,因为其时间复杂度为O(nlogn),效率较高。在处理大规模数据时,堆排序可以提供比较快速的排序结果。
  • 实时系统中的排序:由于堆排序的时间复杂度稳定且较低,适合在实时系统中进行排序操作。在需要快速排序的实时系统中,堆排序可以提供高效的排序解决方案。
  • 优先队列的实现:堆数据结构本身就是一种优先队列的实现方式,堆排序可以用于实现优先队列。在需要按照优先级对元素进行排序和访问的场景中,堆排序可以发挥作用。
  • 外部排序:堆排序也适用于外部排序,即对大规模数据进行排序时,数据无法全部加载到内存中,需要在磁盘上进行排序。堆排序可以在外部排序中提供高效的算法>排序算法

参考链接:
十大经典算法>排序算法(Java实现)


http://www.ppmy.cn/ops/8377.html

相关文章

Qt-控件篇

QPushbutton 1、设置按钮文本 pushButton->setText("按钮"); 2、获取按钮文本 pushButton->text(); 3、设置按钮的大小为特定值&#xff08;宽度和高度&#xff09; pushButton->setFixedSize(width,height); 4、设置按钮悬停时的工具提示文本。 pushButto…

SpringMvc的核心组件和执行流程

一、 springmvc的核心组件及作用 1.DispatcherServlet:前置控制器&#xff0c;是整个流程控制的核心&#xff0c;用来控制其他组件的执行&#xff0c;降低了其他组件的耦合性 2.Handler:控制器&#xff0c;完成具体的业务逻辑&#xff0c;当DispatcherServlet接收到请求后&am…

基于 Spring Boot 博客系统开发(一)

基于 Spring Boot 博客系统开发&#xff08;一&#xff09; 本系统是简易的个人博客系统开发&#xff0c;为了更加熟练地掌握SprIng Boot 框架及相关技术的使用。&#x1f913;&#x1f913;&#x1f913; 本系统开发所需的环境及相关软件 操作系统&#xff1a;Windows Java…

Avalonia 捕获全局异常(UI线程 和 非UI线程),增加客户端的稳定性

在 App.axaml.cs 中&#xff0c;App类添加下列事件&#xff1b; 1.重写 OnFrameworkInitializationCompleted &#xff0c;会在程序初始化完成后触发 2. 绑定AppDomain中当前域的事件 AppDomain.CurrentDomain.UnhandledException HandleGlobalException; //UI线程 …

38. UE5 RPG 修改火球术的攻击方向以及按住Shift攻击

在前面&#xff0c;我们实现了火球术火球的制作&#xff0c;能够在释放火球术时&#xff0c;角色将播放释放技能动画&#xff0c;并实现了对火球的目标的服务器同步功能。 我们先回忆一下之前完成的内容。 在前面&#xff0c;我们先做了一个Actor&#xff0c;用于承载发射的火…

前端HTML面试题:meta 元素都有什么

在HTML中&#xff0c;<meta> 元素是一个非常重要且常用的元素&#xff0c;它用于表示关于HTML文档的元数据&#xff08;metadata&#xff09;&#xff0c;这些元数据不会直接显示在页面上&#xff0c;但可以被浏览器以及其他网页服务利用。在前端开发的面试中&#xff0c…

使用kafka的几种场景

1.消息异步化 在一个分布式的微服务架构中&#xff0c;实现一个聊天的功能&#xff0c;小明和小红互相给对方发消息&#xff0c;如果有两个netty服务器&#xff0c;小明连的是netty服务器1&#xff0c;小红连的是netty服务器2&#xff0c;现在小明给小红发消息&#xff0c;但是…

HTML知识点

知识点搜索网站 MDN 总的理解 这个东西是用来进行界面设计的&#xff0c;可以看成是一些简单的语法规则&#xff0c;然后创作者根据自己的审美&#xff0c;借助这个工具来进行创作 创建 创建一个html文件之后&#xff0c;输入&#xff01;&#xff0c;连续点击三下tab键&a…