堆排序复杂度为O(nlogn),需要注意的误区

2023-11-01 16:59

本文主要是介绍堆排序复杂度为O(nlogn),需要注意的误区,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文希望阐述堆排序O(nlogn)的一些关键细节,摘录一篇博文O(n^2)进行比较。

用作比较的原文 版权声明:为者常成,行者常至

堆排序的特点是优化后的选择排序,其时间复杂度为O(nlogn),下面第一段代码的做法比这个复杂度要高。原因在下文阐述。

堆排序将要排序的对象看做一颗完全二叉树,数据结构可以用数组来实现。


 初始化建堆过程时间:O(n)                                    更改堆元素后重建堆时间:O(nlogn)                                                                         

具体证明可见:http://blog.csdn.net/yuzhihui_no1/article/details/44258297


下面的做法是在建好堆之后,交换堆顶和堆底之后,又执行了重建堆的过程。复杂度应该为O(n^2)。

待比较程序代码如下:

package ex;
import java.util.Arrays;public class Sort {public static void main(String args[]) {  int []a = new int[] {16,25,34,27,30,5,7,4,41,55};Sort.heapSort(a);System.out.println(Arrays.toString(a));}static int parent(int i) {return (i - 1)/2;}static int left(int i) {return 2*i + 1;}static int right(int i) {return 2*i + 2;}static void maxHeapfy(int []a,int i,int heapSize) {   //数组a,第i个结点,heapSize是数组种实际要排序的元素的长度int left = left(i);     //有的时候能够递归到叶子结点,叶子结点无后继,下面两个if都注意到了这一点int right = right(i);   int largest = i;if(left < heapSize && a[left] > a[largest]) {   //largest = left;}if(right < heapSize && a[right] > a[largest])  {largest = right;}if(largest != i) {      //把最大值给父结点a[largest] = a[largest] ^ a[i];a[i] = a[largest] ^ a[i];a[largest] = a[largest] ^ a[i];maxHeapfy(a,largest,heapSize);    //发生交换之后还要保证大根堆性质}}static void buildMaxHeap(int []a,int heapSize) {for(int i = (heapSize-1)/2;i >= 0;i--) {  //此处计算非叶子节点时和计算父节点混淆maxHeapfy(a,i,heapSize);              //此处调用重建堆的过程增加了时间复杂度}}static void heapSort(int []a) {for(int i = a.length-1;i > 0;i--) {buildMaxHeap(a,i+1);   //堆的大小从n到2a[i] = a[0] ^ a[i];    //交换a[0] = a[0] ^ a[i];a[i] = a[0] ^ a[i];}}
}
//输出结果:
//[4, 5, 7, 16, 25, 27, 30, 34, 41, 55]

改进的重建堆的过程


public class HeapSorter implements Sorter{/* (non-Javadoc)* @see A4.Sorter#sort(java.lang.Comparable[])*/@Overridepublic void sort(Comparable[] data) {buildMaxHeap(data,data.length);}int parent(int i){return (i-1)/2;}int left(int i){return 2*i+1;}int right(int i){return 2*i+2;}/*** 将堆排序选出的最大的元素放到数组的最后位置。* 下午10:38:26* 2017年11月29日* @author city*/private void buildMaxHeap(Comparable[] data, int heapSize) {// First Step build Max-heapfor(int i = heapSize/2-1;i>=0;i--) {maxHeapfy(data,i,heapSize);}for(int i = data.length-1;i>0;i--){Comparable tmp = data[i];data[i] = data[0];data[0] = tmp;maxHeapfy(data, 0, i);}}/*** 堆排序算法核心,建立最大堆。* 下午10:39:54* 2017年11月29日* @author city*/private void maxHeapfy(Comparable[] data, int i, int heapSize) {// TODO Auto-generated method stubint left = left(i);int right = right(i);int largest = i;if(left<heapSize && data[left].compareTo(data[largest])>0){largest = left;}if(right<heapSize && data[right].compareTo(data[largest])>0){largest = right;}if(largest!=i){Comparable tmp = data[largest];data[largest] = data[i];data[i] = tmp;maxHeapfy(data, largest, heapSize);}}	
}

如有错误,请指正


比较原文转载自http://blog.csdn.net/qq_35178267/article/details/78313306#insertcode

如有侵权请联系

这篇关于堆排序复杂度为O(nlogn),需要注意的误区的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/324443

相关文章

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

SpringMVC入参绑定特别注意

1.直接在controller中定义一个变量,但是此种传输方式有一个限制就是参数名和请求中的参数名必须保持一致,否则失效。 @RequestMapping("test2")@ResponseBodypublic DBHackResponse<UserInfoVo> test2(String id , String name){UserInfoVo userInfoVo = new UserInf

LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形 题目链接 题目描述 给定一个由 0 和 1 组成的二维矩阵,找出只包含 1 的最大正方形,并返回其面积。 示例1: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4 示例2: 输入: 0 1 1 0 01 1 1 1 11 1 1 1 11 1 1 1 1输出: 9 解题思路 这道题的思路是使用动态规划

argodb自定义函数读取hdfs文件的注意点,避免FileSystem已关闭异常

一、问题描述 一位同学反馈,他写的argo存过中调用了一个自定义函数,函数会加载hdfs上的一个文件,但有些节点会报FileSystem closed异常,同时有时任务会成功,有时会失败。 二、问题分析 argodb的计算引擎是基于spark的定制化引擎,对于自定义函数的调用跟hive on spark的是一致的。udf要通过反射生成实例,然后迭代调用evaluate。通过代码分析,udf在

算法复杂度的简单介绍

算法复杂度是衡量算法执行效率和资源消耗的指标,通常分为时间复杂度和空间复杂度。时间复杂度评估算法执行所需时间随输入规模的变化,空间复杂度评估算法占用内存的增长情况。复杂度通常用大O符号来表示,它描述了最坏情况下的增长速率。 1. 时间复杂度 时间复杂度表示算法执行所需时间随输入规模 nnn 的变化关系。常见的时间复杂度如下(从快到慢): a. 常数时间:O(1) 不管输入大小如何,算法总是

LeetCode:3177. 求出最长好子序列 II 哈希表+动态规划实现n*k时间复杂度

3177. 求出最长好子序列 II 题目链接 题目描述 给你一个整数数组 nums 和一个非负整数k 。如果一个整数序列 seq 满足在下标范围 [0, seq.length - 2] 中 最多只有 k 个下标i满足 seq[i] != seq[i + 1] ,那么我们称这个整数序列为好序列。请你返回 nums中好子序列的最长长度。 实例1: 输入:nums = [1,2,1,1,3],

Vue2电商项目(二) Home模块的开发;(还需要补充js节流和防抖的回顾链接)

文章目录 一、Home模块拆分1. 三级联动组件TypeNav2. 其余组件 二、发送请求的准备工作1. axios的二次封装2. 统一管理接口API----跨域3. nprogress进度条 三、 vuex模块开发四、TypeNav三级联动组件开发1. 动态展示三级联动数据2. 三级联动 动态背景(1)、方式一:CSS样式(2)、方式二:JS 3. 控制二三级数据隐藏与显示--绑定styl