文章目录

  • 简介
  • 排序过程
  • 实现
    • 版本一
    • 版本二
  • 复杂度

简介

约翰·冯·诺伊曼在 1945 年提出了归并排序。归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

归并排序的时间复杂度是O(nlogn)。代价是需要额外的内存空间。

排序过程

实现

版本一
@Test
public void test() {int[] nums = new int[]{4, 2, 8, 9, 6, 3, 5, 7, 1, 2};int[] mergeSort = mergeSortSimple(nums, 0, nums.length - 1);printArray(mergeSort);
}/** 归并排序* @param nums 待排序数组* @param start 开始位置* @param end   结束位置* @return*/
public int[] mergeSortSimple(int[] nums, int start, int end) {if (start == end) {return new int[]{nums[start]};}int mid = (start + end) / 2;int[] m1 = mergeSortSimple(nums, start, mid);int[] m2 = mergeSortSimple(nums, mid + 1, end);return mergeNumsSimple(m1, m2);
}/*** 合并两个有序数组* @param num1 待合并数组1* @param num2 待合并数组2* @return 合并数组
*/
public int[] mergeNumsSimple(int[] num1, int[] num2) {int l1 = num1.length;int l2 = num2.length;int[] resNum = new int[l1 + l2];int resIdx = 0;int index1 = 0;int index2 = 0;while (resIdx < resNum.length) {while (index1 < l1 && index2 < l2) {resNum[resIdx++] = num1[index1] < num2[index2] ? num1[index1++] : num2[index2++];}while (index1 < l1) {resNum[resIdx++] = num1[index1++];}while (index2 < l2) {resNum[resIdx++] = num2[index2++];}}return resNum;
}/*** 打印数组* @param nums
*/
public void printArray(int[] nums) {for (int num : nums) {System.out.print(num + "\t");}System.out.println();
}
版本二
@Test
public void test() {int[] nums = new int[]{4, 2, 8, 9, 6, 3, 5, 7, 1, 2};int[] res = new int[nums.length];mergeSortSimpleOpt(nums, 0, nums.length - 1, res);printArray(res);
}/*** 归并排序
*/
public void mergeSortSimpleOpt(int[] nums, int start, int end, int[] res) {if (start == end) {return;}int mid = (start + end) / 2;mergeSortSimpleOpt(nums, start, mid, res);mergeSortSimpleOpt(nums, mid + 1, end, res);mergeOpt(nums, start, end, res);
}/**
* 版本一递归过程中会有额外的临时数组开销,在此版本优化,直接传入定义好的结果数组做合并
*/
public void mergeOpt(int[] nums, int start, int end, int[] res) {int end1 = (start + end) / 2;int start2 = end1 + 1;int idx1 = start;int idx2 = start2;int resIdx = idx1 + idx2 - start2;while (idx1 <= end1 && idx2 <= end) {res[resIdx++] = nums[idx1] < nums[idx2] ? nums[idx1++] : nums[idx2++];}while (idx1 <= end1) {res[resIdx++] = nums[idx1++];}while (idx2 <= end) {res[resIdx++] = nums[idx2++];}while (start <= end) {nums[start] = res[start++];}
}

复杂度

O(nlogn)

经典排序算法(五) —— Merge Sort 归并排序相关推荐

  1. 经典排序算法 - 冒泡排序Bubble sort

    经典排序算法 - 冒泡排序Bubble sort 其原理是比较接近的数字22,按照从小到交换大或降序排列, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头開始进行两两比較交换,直到倒 ...

  2. 经典排序算法 - 堆排序Heap sort

    经典排序算法 - 堆排序Heap sort 堆排序有点小复杂,分成三块 第一块,什么是堆,什么是最大堆 第二块,怎么将堆调整为最大堆,这部分是重点 第三块,堆排序介绍 第一块,什么是堆,什么是最大堆 ...

  3. 经典排序算法(8)——归并排序算法详解

    归并排序(Merge sort),是创建在归并操作上的一种有效的排序算法,效率为O(nlog n).该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同 ...

  4. [经典排序算法][集锦]

    经典排序算法 经典排序算法,以下文章参考了大量网上的资料,大部分都给出了出处 这一系列重点在理解,所以例子什么的都是最简单的情况,难免失误之处,多指教 大多数排序算法都给出了每一步的状态,以方便初学者 ...

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

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

  6. js【详解】arr.sort()数组排序(内含十大经典排序算法的js实现)

    arr.sort()默认按照Unicode编码,从小到大进行排序,会改变原数组 let arr = ["e", "b", "d", &quo ...

  7. 十大经典排序算法(图解与代码)——冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序(Python and Java)

    排序 重新排列表中的元素,使表中的元素按照关键字递增或者递减 内部排序: 指在排序期间,元素全部存放在内存中的排序 外部排序: 指在排序期间元素无法全部同时存放在内存中,必须在排序的过程中根据要求不断 ...

  8. 十大经典排序算法-归并排序算法详解

    十大经典排序算法 十大经典排序算法-冒泡排序算法详解 十大经典排序算法-选择排序算法详解 十大经典排序算法-插入排序算法详解 十大经典排序算法-希尔排序算法详解 十大经典排序算法-快速排序算法详解 十 ...

  9. Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现

    2017年4月29日~5月1日,国际劳动节, 三天的小长假. 在国内,小长假往往是这样的: 然而我当时在戏称为"德村"(德国农村)的Walldorf出差并且住在Wiesloch, ...

  10. 经典排序算法 - 鸡尾酒排序Cocktail sort

    经典排序算法 - 鸡尾酒排序Cocktail sort 鸡尾酒排序基于冒泡排序,双向循环 还是看例子吧,给定待排数组[2 3 4 5 1] 第一趟过去时的每一步 第一步迭代,2 < 3不换 [2 ...

最新文章

  1. js 与或运算符 || 妙用
  2. (仿头条App项目)9.视频列表页面实现
  3. 对几种二叉树的简单理解
  4. GNS3中不同型号路由器支持的模块表
  5. 剑指offer之二叉树的镜像
  6. 华为音量键只能调通话_华为新全面屏专利曝光,电源键、音量键都没有
  7. VC下ctreectrl的使用方法及节点前图标添加方法
  8. no such file to load -- bundler/setup
  9. 小程序开发,不现实用户的头像!
  10. 蚂蚁金服副总裁刘伟光:浅析银行数字化转型之二「打造金融敏捷中心」
  11. java指标计算_java – 使用JMH计算指标
  12. 中获取当月天数_给商品期货策略加上一个闹钟--策略中的定时设计
  13. 小米adb驱动_腾讯口袋阅、小米多看等电子阅读器如何安装第三方软件!
  14. 实现HTTP下载的几种方式
  15. 玩游戏降频?跑分不行?给你的CPU降降压,提提速!
  16. 杭州的海王星辰将健美生的保健品全部突然下架拉,有谁知道是什么
  17. 计算机网络ieee802.3标准,计算机网络实验四IEEE 802.3协议分析和以太网
  18. java基于微信小程序的游戏外包管理信息系统 uniapp 小程序
  19. bam文件处理 转fq
  20. 金山快盘——大家来注册吧

热门文章

  1. android 如何获全屏幕view内容
  2. charles+小米6(开发版)证书安装
  3. 《华为音乐播放器项目》——1.项目简介与环境搭建
  4. android红包功能程序,微信小程序实现发红包功能
  5. eclipse编译jar中文乱码解决办法
  6. 【问题解决】Vmware虚拟机蓝屏解决方法看这里
  7. 问题 C: 调酒壶里的酸奶
  8. solidity 合约入金出金(eth)
  9. 天津科技大学计算机基础,天津科技大学大学计算机基础样卷.doc
  10. 使命召唤ol显示服务器连接超时,使命召唤online无法连接大厅服务怎么办 无法连接大厅解决方法...