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. docker 发布应用时添加 git revision

    概要 实施步骤 获取 git revision 前端 git revision 注入 后端 git revision 注入 概要 docker 发布应用时, 将 git revision 注入到应用中 ...

  2. Docker学习2-Docker的基本命令与使用

    前言: 前些天有人问镜像是什么?容器有是什么?docker对于初学者来说,往往分不清楚镜像和容器,编程语言都知道有一个面向对象,类和实例,类比作镜像,实例比作容器. 有的人蹦着学习的心态的去群里问人, ...

  3. Navicat 连接远程数据库报错:1130 - Host "XX.XX.XX.XX" is not allowed to connect to this MySQL server

    Navicat 连接远程数据库报错:1130 - Host "XX.XX.XX.XX" is not allowed to connect to this MySQL server ...

  4. linux下发布项目

    查看端口

  5. git rebase的使用: 合并多次commit记录; rebase一个分支的起点

    合并多次commit记录: good:https://blog.csdn.net/csdlwzy/article/details/83379546 使用 git log 命令查看提交历史: 想要合并前 ...

  6. 在linux上安装taiga

    # taiga 安装配置 1.简介 本文档介绍了如何部署完整的Taiga服务(每个模块都是Taiga平台的一部分). Taiga平台由三个主要组件组成,每个组件在编译时和运行时都有自己的依赖关系: t ...

  7. 【前端知识体系-CSS相关】CSS布局知识强化

    1.实现两栏/三栏布局的方法? 表格布局 float + margin布局 inline-block布局 flexbox布局(兼容性的问题) 1.1 基础布局 <style> * { ma ...

  8. scrapy Crawl_spider

    命令行输入:scrapy genspider --list 可以看到scrapy给我们提供的爬虫模板: basiccrawlcsvfeedxmlfeed 一般都是用默认模板生成的spider,如果需要 ...

  9. 12、Render函数

    1.什么是Render函数 Vue 推荐在绝大多数情况下使用模板来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力.这时你可以用渲染函数,它比模板更接近编译器. ...

  10. Markdown温故知新(3):六个实用扩展语法

    目录 1.表格(Table) 2.待办事项或清单(To Do List) 3.自动目录 TOC 4.流程图 5.时序图 6.甘特图 7.总结 1.表格(Table) 没用过 Markdown 表格的人 ...