package com.rao.sort;

import java.util.Arrays;

/**
* @author Srao
* @className MergeSort
* @date 2019/12/7 10:24
* @package com.rao.sort
* @Description 归并排序
*/
public class MergeSort {
/**
* 归并排序:递归写法
* @param arr:要排序的数组
* @param left:数组最左边的元素的下标
* @param right:数组最右边的元素的下标
*/
public static int[] mergeSort(int[] arr, int left, int right){
//如果left == right,那么说明数组中只有一个元素了
if (left < right){
int mid = (left + right) / 2;
arr = mergeSort(arr, left, mid);//对左边的部分进行归并排序
arr = mergeSort(arr, mid+1, right);//对右边的部分进行归并排序
merge(arr, left, mid, right);//将上面两部分进行合并,变成一个有序的数组
}
return arr;
} /**
* 归并排序:非递归写法
* @param arr:要排序的数组
* @return
*/
public static int[] mergeSort2(int[] arr){
int n = arr.length;
//分组时每一轮数组的长度为1,2,4,8,16....
for (int i = 1; i < n; i = i+i){
int left = 0;
int mid = left + i - 1;
int right = mid + i;
while (right < n){
merge(arr, left, mid, right);
left = right + 1;
mid = left + i -1;
right = mid + i;
} //每一次分组合并之后可能会有多余的数组,不够2,4,8...,要把他们也合并到数组里面来
if (left < n && mid < n){
merge(arr, left, mid, n-1);
}
}
return arr;
} /**
* 对数组进行合并
* @param arr:要操作的数组
* @param left:从left到right之间进行合并
* @param mid
* @param right
*/
private static void merge(int[] arr, int left, int mid, int right) {
int i = left;//左边部分的起始下标
int j = mid+1;//右边部分的起始下标
int k = 0;//新数组的下标,新数组用来存放排好序的数字
int[] a = new int[right-left+1];//新数组
while (i <= mid && j <= right){
if (arr[i] < arr[j]){
a[k] = arr[i];
k++;
i++;
}else if (arr[i] >= arr[j]){
a[k] = arr[j];
k++;
j++;
}
}
//把没有排序的数字放入新数组
while (i <= mid){
a[k] = arr[i];
k++;
i++;
}
while (j <= right){
a[k] = arr[j];
k++;
j++;
}
//把新数组中的数字覆盖到旧数组中
for (int m = 0; m < a.length; m++){
arr[left+m] = a[m];
}
} public static void main(String[] args) {
int[] arr = {3, 6, 9, 5, 0};
System.out.println(Arrays.toString(arr));
arr = mergeSort(arr, 0, arr.length-1);
System.out.println(Arrays.toString(arr)); int[] arr2 = {3, 6, 9, 5, 0};
System.out.println(Arrays.toString(arr2));
arr2 = mergeSort2(arr);
System.out.println(Arrays.toString(arr2)); }
}

归并排序的思想:

  把数组一分为二,对左右两边分别进行归并排序,一直往下递归,直到数组不能再分,此时数组中只有一个元素,且一个元素是有序的,再把左右两部分进行合并,一直递归合并成一个有序数组。

排序算法-归并排序(Java)的更多相关文章

  1. 常见排序算法(附java代码)

    常见排序算法与java实现 一.选择排序(SelectSort) 基本原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换:接着对不包括第一个记录以外的其他 ...

  2. 7种基本排序算法的Java实现

    7种基本排序算法的Java实现 转自我的Github 以下为7种基本排序算法的Java实现,以及复杂度和稳定性的相关信息. 以下为代码片段,完整的代码见Sort.java 插入排序 /** * 直接插 ...

  3. 常见排序算法总结 -- java实现

    常见排序算法总结 -- java实现 排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线性时间 ...

  4. 十大经典排序算法(java实现、配图解,附源码)

    前言: 本文章主要是讲解我个人在学习Java开发环境的排序算法时做的一些准备,以及个人的心得体会,汇集成本篇文章,作为自己对排序算法理解的总结与笔记. 内容主要是关于十大经典排序算法的简介.原理.动静 ...

  5. 几大排序算法的Java实现

    很多的面试题都问到了排序算法,中间的算法和思想比较重要,这边我选择了5种常用排序算法并用Java进行了实现.自己写一个模板已防以后面试用到.大家可以看过算法之后,自己去实现一下. 1.冒泡排序:大数向 ...

  6. 经典排序算法 - 归并排序Merge sort

    经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 ...

  7. 几种简单的排序算法(JAVA)

    几种排序算法(JAVA) 一.代码 package com.hdwang; import java.util.Arrays; /** * Created by admin on 2017/1/20. ...

  8. 各排序算法的Java实现及简单分析

    一,直接插入排序 //直接插入排序的算法时间复杂度分析: //如果输入为正序,则每次比较一次就可以找到元素最终位置,复杂度为O(n) //如果输入为反序,则每次要比较i个元素,复杂度为O(n2) // ...

  9. 几大排序算法的Java实现(原创)

    几大排序算法的Java实现 更新中... 注: 该类中附有随机生成[min, max)范围不重复整数的方法,如果各位看官对此方法有什么更好的建议,欢迎提出交流. 各个算法的思路都写在该类的注释中了,同 ...

  10. 数据结构和算法(Golang实现)(23)排序算法-归并排序

    归并排序 归并排序是一种分治策略的排序算法.它是一种比较特殊的排序算法,通过递归地先使每个子序列有序,再将两个有序的序列进行合并成一个有序的序列. 归并排序首先由著名的现代计算机之父John_von_ ...

随机推荐

  1. 慕课网springboot博客系统开发(一)----spring initializr的使用 gradle构建项目

    spring initializr工具的地址:https://start.spring.io/:通过它可以很方便的创建springboot项目 这里我们选择使用gradle作为项目的构建工具,此spr ...

  2. Navicat的安装和pymysql模块的使用

    内容回顾 select distinct 字段1,字段2,... from 表名 where 分组之前的过滤条件 group by 分组条件 having 分组之后过滤条件 order by 排序字段 ...

  3. RabbitMQ操作代码封装

    1.Message.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; u ...

  4. 基于 Docker 实现 DevOps 的一些探索

    DevOps 介绍 DevOps(Deveplopment 和 Operations 的简称),中译为开发运维一体化,可定义为是一种过程.方法.文化.运动或实践,主要是为了通过一条高度自动化的流水线来 ...

  5. xunsearch强制刷新

    $index = $xs->index; $index->flushLogging(); 等价于 util/Indexer.php --flush-log demo

  6. C# foreach循环

    一.简介 foreach循环可以迭代数组或者一个集合对象 二.语法 foreach(数据类型  变量名  in  数组名) {     //语句块: } 循环运行的过程:每一次循环时,从集合中取出一个 ...

  7. StackExchange.Redis 封装

    博主最近开始玩Redis啊~~ 看了很多Redis的文章,感觉有点云里雾里的,之前看到是ServiceStack.Redis,看了一些大佬封装的Helper类,还是懵懵的QAQ 没办法啊只能硬着**上 ...

  8. 获取Ext Tree选中的节点

    获取Ext Tree选中的节点 text: '确认', handler: function () { //获取当前选中树的节点方法 var ck = rightsTree.getChecked(); ...

  9. Math基础使用

    /* java.lang.Math类是数学相关的工具类,里面提供的大量静态方法,完成与数学运算的操作 public static double abs(double num):获取绝对值. publi ...

  10. spring事务概念与获取事务时事务传播行为源码分析

    一.事务状态:org.springframework.transaction.TransactionStatus isNewTransaction 是否是新事务 hasSavepoint 是否有保存点 ...