首页 > 编程语言 >归并排序算法 java实现

归并排序算法 java实现

时间:2024-03-20 20:58:08浏览次数:17  
标签:归并 java 数组 int arr mid 拆分 排序 left

public static void main(String[] args) {
    int[] arr = {9, 5, 7, 3, 1, 6, 8, 4, 2};
    mergeSort(arr,0,arr.length - 1);
}

/**
 * 归并排序
 * 注意:归并的拆分数组和合并数组是从左到右依次进行的,网上很多文章都是错误的
 * 并不是左右一起拆分,网上很多文章都是这样的拆分图,其实是不对的
 * 9,5,7,3,1,6,8,4,2
 * 9,5,7,3,1      6,8,4,2 第一次拆分
 * 9,5,7   3,1    6,8    4,2    第二次拆分
 * 而是
 * 9,5,7,3,1,6,8,4,2
 * 9,5,7,3,1     6,8,4,2            第一次拆分,右边数组不动,因为一直在递归的是左边数组中的
 * 9,5,7   3,1   6,8,4,2            第二次拆分,右边数组不动,因为一直在递归的是左边数组中,此时左边数组又拆分成2个数组
 * 9,5     7     3,1      6,8,4,2   第三次拆分,右边数组还不动,因为一直在递归的是左边数组中的,左边再拆分至单个元素,单个元素我们认为就是有序
 * 5,9     7     3,1      6,8,4,2   开始合并第三次拆分的数组
 * 5,7,9   3,1   6,8,4,2            开始拆3,1的数组,再拆的话就是单个元素了
 * 5,7,9   3  1  6,8,4,2            拆完左右都是单个元素
 * 5,7,9   1,3   6,8,4,2            单个元素认为是有序的,所以合并成一个有序数组
 * 5,7,9,1,3     6,8,4,2            合并第二次拆分的数组
 * 1,3,5,7,9     6,8,4,2            至此,第一次拆分的左边的数组已经排好序,下面开始拆分右边的数据
 * 1,3,5,7,9     6,8    4,2         此时才拆分右边的数据,重复上面步骤
 * @param arr
 * @param left
 * @param right
 */
private static void mergeSort(int[] arr, int left, int right) {
    //表示递归的限定条件,如果左边界和右边界相等,说明已经拆分到最小单元的元素了,直接返回开始合并
    if (left >= right) {
        return;
    }
    int mid = left + (right - left) / 2;
    mergeSort(arr,left,mid); //对于左边数组来说,mid就是右边界
    mergeSort(arr,mid + 1,right); //对于右边数组来说,mid + 1就是左边界
    merge(arr,left,mid,right);//开始合并,左边的数组(第一次拆分的数组)合并完成,才会拆分和合并右边(第一次拆分)的数组
    System.out.println(Arrays.toString(arr));

}

private static void merge(int[] arr, int left, int mid, int right) {
    //临时数组用来存储合并之后的有序元素
    int[] temp = new int[right -left + 1];
    //左数组的初始下标
    int i = left;
    //右数组的初始下标,mid同时也是左边数组的右边界
    int j = mid + 1;
    //临时数组的初始下标
    int k = 0;
    //左右两个数组开始比较,合并到临时数组中
    while (i <= mid && j <= right) {
        if (arr[i] <= arr[j]) {
            //左边数组的下标移动,右边数组下标不动
            temp[k++] = arr[i++];
        } else {
            //右边数组的下标移动,左边数组下标不动
            temp[k++] = arr[j++];
        }
    }

    //说明左边数组还有剩余的元素,直接全部放入temp数组中,因为多余的肯定是排好序的而且都是比当前temp中元素大的值
    while (i <= mid) {
        temp[k++] = arr[i++];
    }
    //说明右边数组还有剩余的元素,直接全部放入temp数组中,因为多余的肯定是排好序的而且都是比当前temp中元素大的值
    while (j <= right) {
        temp[k++] = arr[j++];
    }
    //已经排好序的临时数组,要复制到原数组中,下标肯定是从left开始
    for (int t : temp) {
        arr[left++] = t;
    }

}

标签:归并,java,数组,int,arr,mid,拆分,排序,left
From: https://www.cnblogs.com/Houqz/p/18086044

相关文章

  • Java中String类型的创建与比较(详解)
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、String类型是什么??二、String类型的创建使用字符串字面量使用new关键字intern()方法简读图解String的比较总结前言提示:这里可以添加本文要记录的大概内容:在背八股文(Holis版)的过程中遇......
  • Java 越来越卷,掌握哪些知识才有机会进大厂?来看各个大厂AI 大模型怎么说?
    通义千问(阿里)在当前竞争激烈的Java开发市场中,为了增加进大厂和获得更好职业发展的机会,Java开发者应关注以下几个核心知识点与技能:基础扎实:•熟练掌握Java基础语法、面向对象设计原则、集合框架、多线程并发编程、异常处理机制等基础知识。•对JVM内存模型、垃圾回......
  • java基础的项目
    334,零钱通   思路:(1)先完成显示菜单,并可以选择菜单,给出对应提示(2)完成零钱通明细,简单的话可以使用String拼接(3)完成收益入账  完成功能驱动程序员增加新的变化和代码(4)消费(5)退出(6)用户输入4退出时,给出提示"你确定要退出吗?y/n",必须输入正确的y/n,否则循环输入指令,直到......
  • (day 13)JavaScript学习笔记(对象1)
    概述        这是我的学习笔记,记录了JavaScript的学习过程。在写博客的时候我会尽量详尽的记录每个知识点。如果你完全没接触过JavaScript,那么这一系列的学习笔记可能会对你有所帮助。    今天学习对象,主要是创建对象、对象属性、省略key、遍历对象属性、删......
  • JavaScript中的“==“和“===“运算符的区别
    JavaScript中的比较运算符"=="和"==="用于比较两个值是否相等。尽管它们的目的相同,但它们在比较过程中采用了不同的策略1.“==”相等运算符:"=="运算符执行一种松散相等比较,它在比较之前会进行类型转换。如果进行比较的两个值类型不同,JavaScript会尝试将它们......
  • x == (x = y) 与 (x = y) == x 不同?【Java 面试题】
    x==(x=y)与(x=y)==x不同?classQuirky{publicstaticvoidmain(String[]args){intx=1;inty=3;System.out.println(x==(x=y));//falsex=1;//resetSystem.out.println((x=y)==x);//......
  • java中的抽象类不能被实例化,那为什么还有构造方法
    java中的抽象类不能被实例化,那为什么还有构造方法java中的类必须要有构造方法(无参和/或有参)(没有的话编译不过);如果没有显示定义,那编译器会默认给该类创建一个无参构造方法抽象类如果能实例化,那被实例化的这个对象就可以调用该类中定义的所有方法(包括抽象方法),但是抽象方法......
  • java 继承(中)
    前面我们已经说明了什么是继承?继承的好处弊端等,不清楚的可参照链接java继承(上)-CSDN博客本篇文章主要理解super和this的区别及联系。1、super本章节主要说明怎么访问方法内的变量,类内的成员变量,父类的成员变量,下面先看代码实现。1.1代码实现(1)Fu类的代码实现publiccla......
  • 提升Java编程安全性-代码加密混淆工具的重要性和应用
     在Java编程领域中,保护代码安全性和知识产权至关重要。本文旨在探讨代码加密混淆工具在提升代码安全性和保护知识产权方面的重要性。我们将介绍几款流行的Java代码加密混淆工具,如ProGuard、DexGuard、Jscrambler、DashO和ipaguard,并分析它们的功能和适用场景,旨在帮助开发者选择......
  • 卡码java基础课 | 16.出现频率最高的字母
    学习内容:哈希表:数组重点归纳:哈希表:根据关键码key的值而直接进行访问的数据结构。重点是哈希函数(散列函数),是一种对应关系f,根据关键字找到对应存储位置。大致分为3种,数组、set集合、map映射。本节主要学习数组作为哈希表的使用。例题:解:点击查看代码importjava.util.Scan......