【JavaDS】排序——快排 & 归并

简介: 【JavaDS】排序——快排 & 归并

上接【JavaDS】排序——快速排序

快排的另一种 partition 方法


通过算法的设计将序列分成如图所示的三个区间


               [ from, s )               元素 <= pivot


               [ s, i )                     元素 >= pivot


               [ i, to )                    待比较元素


遍历 [ from, to )


比较 array[i] 和 pivot ,array[i] < pivot ,交换 i 和 s 的元素,同时 i++,s++;


                                    array[i] > pivot, i++;


遍历比较完成之后,交换 pivot 和 s 的值


13.png

代码参考

private static int partitionMethodC(long[] array, int from, int to) {
        int s = from;
        long pivot = array[to];
        for (int i = from; i < to; i++) {   // 遍历 [from, to)
            // 这里加 == 号也保证不了稳定性,有交换操作
            if (array[i] < pivot) {
                // TODO: 可以进行简单的优化:如果 i == s,就不交换
                long t = array[i];
                array[i] = array[s];
                array[s] = t;
                s++;
            }
        }
        array[to] = array[s];
        array[s] = pivot;
        return s;
    }

快排的几个常见优化手段

1. 前提结论:在待排序元素比较少的情况下,快排的速度低于插排,所以,在待排序元素个数的个数低于一个阈值(20)时,直接使用插排完成


2. partition 算法上的优化(比如,把 == pivot 的提前找出来),


               同时选择多个基准值,比如三个,记为 p1, p2, p3, 其中 p1 < p2 < p3 , 如下图所示


3. 选择 pivot 的方式上优化


       三数取中法


               取区间最开始,最中间以及最后面的三个数,取这三个数大小上是中间的数作为基准值,最后再把确定的基准值交换到区间最后面


14.png


归并排序

将区间分成如图所示的两个小区间,如果可以使左右两个区间都变得有序,那么合并两个有序区间之后,整个区间变得有序

归并排序的基本思想

1. 如果待排序区间已经有序(区间内的元素个数 <= 1),则排序操作直接返回


2. 确定区间中间位置的下标 mid ( mid = from + (size / 2)),所以 [ from, to ) 的区间,被我们从逻辑上视为是左右两个小区间([ from, mid) 和 [ mid, to ))组成


3. 先对左右两个小区间使用相同的方法,进行排序


4. 当左右两个小区间已经有序时,执行合并两个有序区间的操作,得到一个最终的有序大区间


具体步骤演示


15.png


和并两个小区间为一个有序大区间的方法

合并两个有序区间,需要用到同等大小的一个额外空间

从两个区间分别挑出最小的元素比较,确定两个元素在新区间内的相对位置,循环执行此过程,直至一个小区间内的元素全部被比较,如果另一个区间内还有元素,则按照顺序插入新区间即可


代码参考

private static void merge(long[] array, int from, int mid, int to) {
        // 先计算出来额外空间需要多个,计算两个区间加起来多少个元素
        int size = to - from;
        // 申请一个额外的数组作为临时保存的地方
        long[] other = new long[size];  // 需要一个 和 n 长度一致的空间
        int left = from;    // 左边小区间的下标
        int right = mid;    // 右边小区间的下标
        int dest = 0;       // 临时空间的下标
        // 只要左右两个小区间还有元素要参与比较
        while (left < mid && right < to) {
            if (array[left] <= array[right]) {
                other[dest++] = array[left++];
            } else {
                other[dest++] = array[right++];
            }
        }
        // 其中一个区间的元素取完了,另一个区间里一定还有元素,再把剩余的元素,统统放入 other
        // 看起来左右两个都写了,但执行起来的时候一定只有一个会执行
        while (left < mid) {
            other[dest++] = array[left++];
        }
        while (right < to) {
            other[dest++] = array[right++];
        }
        // 把 other 中的有序元素,复制回 array 中,要注意下标的问题
        for (int i = 0; i < size; i++) {
            array[from + i] = other[i];     // array 下标的基准是从 [from] 开始,other 下标的基准是从 [0] 开始
                                            // offset(偏移)是一致的,都是 i
        }
    }


7 种基于比较的排序

快速排序、归并排序、冒泡排序、插入排序、希尔排序、选择排序、堆排序


按照不同的标准,划分这些排序


1. 具备稳定性的排序:冒泡、插排、归并


2. 平均情况下,执行速度分为两组:


       1)慢:冒泡、插排、选择——排序的元素个数在 10万 级别左右


       2)快:快排、归并、希尔、堆排——个数在 1忆 级别


3. 空间角度


       1)空间复杂度是 O(1) :冒泡、插排、希尔、选择、堆排


       2)空间复杂度是 O(log(n) ~ O(n)):快排


       3)空间复杂度是 O(n):归并


4. 属于减治算法(每次问题规模减少1):冒泡、插排、希尔、选择、堆排


   属于分治算法(把问题分成多个子问题分别处理):快排、归并


目录
相关文章
|
5月前
|
存储 缓存 安全
2026年阿里云服务器最新按量、包年包月收费标准与云服务器活动价格汇总
2026年,阿里云推出多种云服务器活动,2核2G轻量应用服务器最低38元1年,2核4G云服务器199元1年,u2i实例4核8G云服务器1252.63元1年起,满足不同用户需求。收费标准包括实例配置、带宽和云盘价格,实例类型多样,如经济型e、通用算力型u1、计算型c9i等。用户可根据业务需求、预算及扩展计划选择适合的实例。
973 0
|
5月前
|
人工智能 自然语言处理 监控
《QClaw重构开发的四个底层逻辑,看懂少走半年弯路》
本文直击传统开发自动化“维护工具比省时间还多”的普遍痛点,深度剖析QClaw与普通对话式AI的本质差异——它是具备本地系统级执行能力的智能体,而非简单的聊天助手。文章结合真实使用经验,分享了串联原子能力构建完整工作流、利用事件驱动搭建全自动开发环境、远程异步处理碎片化任务、引导智能体个性化适配四个核心实践,提出未来程序员将从代码编写者转变为智能体训练师的核心观点,为技术从业者重构开发流程提供了可落地的新思路。
423 0
|
6月前
|
移动开发 NoSQL 前端开发
从零到一:游戏陪玩系统的技术架构与业务设计| 多端实战
本文分享基于ThinkPHP6+Uniapp重构的游戏陪玩系统实战经验,涵盖五角色权限设计、订单状态机、Redis抢锁、邀请裂变等核心实现,强调业务梳理重于技术选型,代码开源可二次开发。(239字)
842 2
|
8月前
|
数据采集 监控 数据可视化
你的数据质量可靠吗?一份评估数据质量的实用指南
数据质量是企业数据驱动的生命线。本文深入探讨其六大核心维度:准确性、完整性、一致性、及时性、唯一性与有效性,解析低质数据带来的决策失误、效率低下等痛点,并分享如何通过业务与技术协同,借助工具实现质量规则的自动化监控与持续改进,构建可信数据体系。
|
9月前
|
数据采集 运维 调度
Dataphin功能Tips系列(88)补数据场景下,如何实现质量规则的精准回溯校验?
在数据补跑场景中,为精准校验指定历史日期(如12月18日)的数据,质量管理员应使用基于业务日期的表达式 ds=&#39;${yyyyMMdd}&#39; 配置调度规则。该方式支持手动执行时动态关联所选业务日期,确保校验范围准确指向目标数据,实现高效、精确的质量校验。
302 0
|
11月前
|
消息中间件 运维 监控
《聊聊分布式》BASE理论 分布式系统可用性与一致性的工程平衡艺术
BASE理论是对CAP定理中可用性与分区容错性的实践延伸,通过“基本可用、软状态、最终一致性”三大核心,解决分布式系统中ACID模型的性能瓶颈。它以业务为导向,在保证系统高可用的同时,合理放宽强一致性要求,并借助补偿机制、消息队列等技术实现数据最终一致,广泛应用于电商、社交、外卖等大规模互联网场景。
|
12月前
|
机器学习/深度学习 人工智能 自然语言处理
大模型
大模型正重塑数字世界,以千亿级参数和深度学习技术驱动AI革命。它赋能内容生成、智能交互与知识服务,同时带来伦理、隐私与能耗挑战。未来需走向高效、可信、向善的可持续发展之路。
|
传感器 存储 数据采集
深入调查研究GE-Predix
【11月更文挑战第8天】
1969 2
|
人工智能 物联网 Python
VMix:即插即用!字节联合中科大推出增强模型生成美学质量的开源适配器,支持多源输入、高质量视频处理
VMix 是一款创新的即插即用美学适配器,通过解耦文本提示和交叉注意力混合控制,显著提升图像生成的美学质量,支持多源输入和高质量视频处理。
850 11
VMix:即插即用!字节联合中科大推出增强模型生成美学质量的开源适配器,支持多源输入、高质量视频处理
|
运维 监控 安全
宝塔Windows面板:轻松管理服务器的图形化神器
宝塔Windows面板是一款专为Windows服务器用户设计的图形化管理工具,旨在简化IIS配置、环境搭建与安全管理等复杂操作。它支持一键部署全栈运行环境(如IIS/Apache、PHP、MySQL等),提供可视化站点管理、安全防护与监控功能,并拥有丰富的插件生态。无论是个人站长、开发者还是中小企业,都能通过这款免费工具快速搭建网站、优化性能并强化安全性。尽管在高版本IIS兼容性和插件丰富度上略逊于Linux版,但其零门槛操作和全面功能仍使其成为理想的入门级服务器管理解决方案。
1394 5