排序算法-归并排序

归并排序是一种**分治算法(Divide and Conquer)。**对于给定的一组数据,利用递归与分治技术将数据序列划分成为越来越小的半子表,在对半子表排序后,再用递归方法将排好序的半子表合并成为越来越大的有序序列。

核心思想

  1. 分解(Divide):将数组递归地分成两半,直到子数组长度为 1。

  2. 合并(Merge):将两个已排序的子数组合并成一个有序数组。

合并的过程

代码实现

java 复制代码
package Sort;

import java.util.Arrays;

public class MergeSort {
    public static void main(String[] args) {
        int[] res = getMergeSort(new int[]{8,5,7,9,1,6,3,4,2});
        for (int i = 0; i < res.length; i++) {
            System.out.print(res[i]+" ");
        }
    }
    //使用递归实现归并排序,升序
    public static int[] getMergeSort(int[] nums){
        if (nums.length<2) return nums;
        //切分数组,然后递归排序,并用merge合并
        int mid = nums.length/2;
        int[] leftNums = Arrays.copyOfRange(nums,0,mid);
        int[] rightNums = Arrays.copyOfRange(nums,mid,nums.length);
        return merge(getMergeSort(leftNums),getMergeSort(rightNums));
    }
    public static int[] merge(int[] leftNums,int[] rightNums){
        int[] result = new int[leftNums.length + rightNums.length];

        for (int index = 0, i = 0, j = 0; index < result.length ; index ++) {
            if (i>=leftNums.length){// 左边数组已经取完,那就完全取右边数组即可
                result[index] = rightNums[j++];
            } else if (j>=rightNums.length) { // 右边数组已经取完,那就完全取左边即可
                result[index] = leftNums[i++];
            } else if (rightNums[j] < leftNums[i]) { // 升序:右边数组的元素小于左边数组,取右边数组的值
                result[index] = rightNums[j++];
            }else { // 升序:左边数组的元素小于右边数组,取左边数组的值
                result[index] = leftNums[i++];
            }
        }
        return result;
    }


}

时间复杂度分析

情况 时间复杂度 说明
最坏情况 O(n log n) 无论输入数据如何分布,都必须完整执行所有分解和合并操作
最好情况 O(n log n) 即使输入已经有序,仍需进行全部合并操作
平均情况 O(n log n) 算法性能稳定,不受输入数据分布影响

空间复杂度分析

组成部分 空间消耗 说明
临时数组 O(n) 合并操作需要与原始数组等大的临时存储空间
递归调用栈 O(log n) 递归深度为 log₂n,每层递归需要保存常数级的参数
总空间 O(n) 临时数组的空间占用主导(通常说的空间复杂度指除输入外的额外空间需求)
相关推荐
缓慢更新7 小时前
审批的加签与会签:多人意见怎么合
android·java·数据库·低代码·rxjava
yuniko-n8 小时前
【JUC】volatile 非原子性深入解析
java
sun_weitao8 小时前
极简版 MCP 工具实现方案
java·linux·服务器
金銀銅鐵9 小时前
[Java] 展示增删元素时 LinkedList 的内部变化
java·后端·ai编程
布吉岛的石头10 小时前
Java 程序员第 50 阶段3:数据工程:预训练语料清洗与去重
java·开发语言·人工智能·深度学习·transformer
大文说跨境10 小时前
防关联浏览器的指纹覆盖到什么程度:六类参数的实测与自检方法
java·指纹浏览器·tiktok运营
Carol063011 小时前
上肢及肩肘关节
java·服务器·数据库
yliucherish11 小时前
Log4Shell 复现实录:我读 OpenJDK 源码,发现两道防线的默认值竟然相反
java
维拉德11 小时前
Java新人第一次接打标需求:从抓包找接口到客户端展示
java
luobobo89611 小时前
支付回调验签连续失败三天,最后发现是网关的时间戳单位问题
java