三大O(nlogn)算法分析

news2024/12/28 5:29:36

堆排序

demo

从第一个父节点开始,每一个都调换自己和所有子孙节点的上下层次调换,形成最大堆。然后进行堆分支调整

class Solution {
    public int[] sortArray(int[] nums) {
        maxHeap(nums);
        sort(nums);
        return nums;
    }

    public static void maxHeap(int[] nums){
        int limit = nums.length-1;
        System.out.println(limit<<1+1);
        for(int i=limit>>1;i>=0;i--){
            changeForRoot(i,limit,nums);
        }
    }

    public static void sort(int[] nums){
        int limit = nums.length-1;
        while(limit>0){
            swap(nums,0,limit);
            limit--;
            changeForRoot(0,limit,nums);
        }
    }

    public static void changeForRoot(int root,int limit,int[] nums) {
        for (int i = root; ((i << 1) + 1) <= limit; ) {
            int lChild = (i << 1) + 1;
            int rChild = (i << 1) + 2;
            int change = i;
            if (lChild <= limit && nums[lChild] > nums[change]) {
                change = lChild;
            }
            if (rChild <= limit && nums[rChild] > nums[change]) {
                change = rChild;
            }
            if(i==change){
                break;
            }
            swap(nums, i, change);
            i = change;
        }
    }

    public static void swap(int[] nums,int a,int b){
        int tmp = nums[a];
        nums[a] = nums[b];
        nums[b] = tmp;
    }
}

易错点

1 需要明白堆排序是一个O(nlogn)的算法,不要把第一次O(n)的堆遍历调整当成调整节点的方法,否则会变为O(n²)
2 第一次排序,每一个点都要和自己的子节点比较,然后比较之后,如果有顺序调整,还需要继续和孙节点进行比较,这个递归过程就是调整节点的步骤,复杂度为O(logn),因为进行了n次,所以总复杂度为O(nlogn)

归并排序

demo

class Solution {
    private int[] arr;

    public int[] sortArray(int[] nums) {
        arr = new int[nums.length];
        int rPoint = nums.length-1;
        split(nums,0,rPoint);
        return nums;
    }

    public void split(int[] nums,int left,int right) {
        if(left>=right){
            return;
        }
        int mid = (right-left)/2+left;
        split(nums,left,mid);
        split(nums,mid+1,right);
        merge(nums,left,mid,right);
    }

    public void merge(int[] nums,int left,int mid,int right){
        int point = left;
        int l = left;
        int r = mid+1;
        while(l<=mid&&r<=right){
            arr[point] = nums[l]<=nums[r]?nums[l++]:nums[r++];
            point++;
        }
        while(l<=mid){
            arr[point++] = nums[l++];
        }
        while(r<=right){
            arr[point++] = nums[r++];
        }
        for(int i=left;i<=right;i++){
            nums[i] = arr[i];
        }
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

易错点

一开始博主忘了底层算法,结果底层在冒泡和插入考虑,最终敲定插入然后就超时了,需要记得底层算法是双指针算法,由于最后一次合并过程必定需要一个O(n)空间,所以不如一开始就一直初始化这样大的空间。

快速排序

demo

class Solution {
    public int[] sortArray(int[] nums) {
        split(nums,0,nums.length-1);
        System.out.println();
        return nums;
    }

    private void split(int[] nums,int left,int right){
        if(left>=right) return;
        int pivot = sort(nums,left,right);
        split(nums,left,pivot);
        split(nums,pivot+1,right);
    }

    private int sort(int[] nums,int left,int right){
        setPivot(nums,left,right);
        int change = left;
        int val = nums[right];
        for(int i=left;i<right;i++){
            if(nums[i]<val){
                swap(nums,change,i);
                change++;
            }
        }
        swap(nums,right,change);
        return change;
    }

    private void setPivot(int[] nums,int left,int right){
        int pivot = left+(int)((right-left+1)*Math.random());
        swap(nums,right,pivot);
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

易错点

以下两个点很容易发现,但容易卡或者失去bug free
1 底层交换时,如果小于pivot,就提到change,然后change++,一开始博主想的是小于pivot,change右移,大于pivot,change++,脑子短路了
2 随机计算时要注意+1

总结

小数据选插入
大数据,对象选归并,因为稳定,如果是基础类型的话有结构选归并,无结构选快速
在Arrays.sort中插入和其它排序选择的转折点为47

为什么不用堆排,这个博客总结得很好,https://blog.csdn.net/csdnwxhw/article/details/119037375
1是因为堆本身就有一定的上下顺序,所以每次调整都大概率从尾到顶,而且父子节点有2倍索引差距,很容易造成随机读取,io消耗大
请添加图片描述

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

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

相关文章

blender hardOps插件

hardOps将一些常用的功能整合在一起&#xff0c;方便调用&#xff0c;例如&#xff0c;平滑&#xff0c;倒角&#xff0c;标记锐边&#xff0c;添加修改器 打开hardOps 方法1&#xff1a;物体模式在舞台左侧选择hardOps图标 推荐用这个 方法2&#xff1a;这个插件的打开方式非…

C++【类型转换】

文章目录一、C语言的类型转换二、C的强制类型转换1.static_cast静态转换2.reinterpret_cast重新诠释3.const_cast小总结4.dynamic_cast动态转换一、C语言的类型转换 在C语言中&#xff0c;如果赋值运算符左右两侧类型不同&#xff0c;或者形参与实参类型不匹配&#xff0c;或者…

【PAT】数据结构树和图月考复习1

选择题 2-1 我们用一个有向图来表示航空公司所有航班的航线。下列哪种算法最适合解决找给定两城市间最经济的飞行路线问题&#xff1f; A.深度优先搜索 B.Kruskal算法 C.拓扑排序算法 D.Dijkstra算法 解析&#xff1a; 本题为单源最短路径问题&#xff0c;应选用dijsktra算…

【WMWare 克隆CentOS虚拟机 】解决克隆后 ip 冲突 主机名重复问题

前言&#xff1a; 当我需要搭建数据库主从复制集群时&#xff0c;不想再重新安装一遍 mysql &#xff0c;于是将安装好 mysql 的虚拟机克隆一份 一、克隆方法 鼠标右击虚拟机 ----> 管理 ----> 克隆 &#xff08;选择完全克隆&#xff0c;选择好位置&#xff0c;设置好…

python函数使用

目录 一.函数基本概念 1.函数是什么 2.使用函数的好处是: 3.为什么要学习、使用函数 二.函数使用 1.定义方法 2.函数的调用 3.注意事项 4.例子 三.函数中的参数 作用 注意 四.函数中的返回值 1.什么是函数返回值? 2.返回值的应用语法: 注意 五.None类型 一.函数…

Android茶叶进销存

功能描述: 该app主要实现了茶叶的进货、销售、供应商、客户的管理&#xff0c;是一个完整的小型进销存app&#xff0c;适合新手学习sqlite数据库的基本使用。具体功能如下&#xff1a; 一、个人业务管理子系统 1、客户信息登记、修改、注销&#xff08;客户管理&#xff09; …

[Linux](15)线程基础,线程控制,线程的互斥与同步

文章目录前言Linux 线程概念线程的优点线程的缺点线程异常线程用途使用pthread_createpthread_join线程退出线程id分离线程线程互斥问题&#xff1a;临界资源访问问题问题解决&#xff1a;互斥锁的使用RAII 风格的加锁方式可重入 & 线程安全死锁的概念线程同步条件变量生产…

[附源码]计算机毕业设计springboot春晓学堂管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

让我们进入面向对象的世界(四)

文章目录前言一. 初始多态1.1 多态是什么1.2 多态是怎么工作1.3多态的向上转型和向下转型二.多态的好处三.总结前言 前面我们讲过了&#xff0c;面向对象继承的特性&#xff0c;下面我们会根据多态来展开讨论&#xff0c;还是用熟悉的方式&#xff0c;让大家去了解这个疯狂的东…

软考证书具体用途--详细介绍

拿到软考证书的前提是对你自己今后的职业发展有帮助&#xff0c;用得到才能对你而言发挥它最大的好处。 软考证书的具体用途&#xff1a; 1.纳入我国高校人才培养和教学体系 目前&#xff0c;软考已经被纳入高校人才培养和教学体系。在很多高校中&#xff0c;软考纳入学分&a…

设置渐变边框色

如上图所示&#xff0c;需设置渐变边框色&#xff0c;左右边框颜色固定&#xff0c;上边框从左到右开始渐变&#xff0c;下边框从右到左开始渐变。 思考了很久&#xff0c;如果看作是一个div&#xff0c;则需要用到 border-image属性设置渐变色。也可以看作是两个div&#xff0…

北大学者发现,经常喝牛奶,增加中国人肝癌和乳腺癌风险

牛奶是生活中常见的饮品。牛奶含有丰富的蛋白质&#xff0c;钙元素等多种营养成分&#xff0c;能为人体提供充足的蛋白质和钙&#xff0c;增强人体的体质&#xff0c;提高免疫力。然而&#xff0c;无论是什么&#xff0c;物极必反&#xff0c;过量饮用也会对身体产生不利的影响…

2022Flink大数据比赛项目-焦点科技大数据编程大赛

文章目录0.数据获取1.需求概要2.数据标准2.1.输入数据格式2.2.输出数据格式2.3.数据主键及关系3.表详细1.order_info2.bill_info3.bill_item4.ord_pay5.ord_pay_log6.pay_method7.pay_bank_card4.开发工具、语言版本、工具版本5.赛题解答数据分流任务1任务2任务3小结附录0.数据…

股票详情接口是怎样开发的?

一般情况下&#xff0c;在量化市场中&#xff0c;投资者使用的辅助炒股软件就包括很多数据接口&#xff0c;特别是股票详情接口系统更为可见&#xff0c;不过在使用之前&#xff0c;也是需要提前了解清楚它的开发原理&#xff0c;以及使用规则等&#xff0c;那么它是怎样开发出…

麦芽糖-链霉亲和素maltose-Streptavidins链霉亲和素-PEG-麦芽糖

麦芽糖-链霉亲和素maltose-Streptavidins链霉亲和素-PEG-麦芽糖 中文名称&#xff1a;麦芽糖-链霉亲和素 英文名称&#xff1a;maltose-Streptavidins 别称&#xff1a;链霉亲和素修饰麦芽糖&#xff0c;链霉亲和素-麦芽糖 提供PEG接枝修饰麦芽糖&#xff0c;麦芽糖-聚…

易观千帆 | 2022年10月银行APP月活跃用户规模盘点

易观分析&#xff1a;易观千帆数据显示&#xff0c;10月手机银行服务应用活跃人数52285.79万&#xff0c;环比下降3.52%。手机银行服务应用月活规模经历了连续5个月的持续增长后&#xff0c;10月出现下降。 10月城商行手机银行服务应用活跃人数3565.56万&#xff0c;环比下降2…

线程的概念和创建【javaee初阶】

目录 一、认识线程 二、多线程程序 2.1 实现Java多线程程序 方法1 继承 Thread &#xff0c;重写run 方法2 实现 Runnable 接口 方法3 匿名内部类创建 Thread 子类对象 方法4 匿名内部类创建 Runnable 子类对象 方法5 lambda 表达式创建 Runnable 子类对象 三、多线程的…

Kamiya丨Kamiya艾美捷小鼠高敏CRP ELISA说明书

Kamiya艾美捷小鼠高敏CRP ELISA预期用途&#xff1a; 小鼠高敏CRP ELISA是一种高灵敏度的双位点酶联免疫分析&#xff08;ELISA&#xff09;定量测定小鼠生物样品中的C-反应蛋白&#xff08;CRP&#xff09;。仅供研究使用。 引言 急性期蛋白质是血浆蛋白质&#xff0c;其在感…

交互作用的深入剖析

1.原理说明 交互作用(Interaction effect)指两个或多个因素&#xff08;比如A因素和B因素&#xff09;对于某项&#xff08;比如身高&#xff09;的影响时&#xff0c;A因素和B因素各个水平之间是否存在着相互作用关系。比如A因素为性别&#xff0c;B因素为区域&#xff0c;男…

Springboot+vue+java幼儿园管理系统

开发语言&#xff1a;Java 框架&#xff1a;springboot 前端框架:vue.js JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat8 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/idea 目 录 第一章 绪 论 1 1.1背景及意义 1…