归并排序可以采用递归方法(见:归并排序),但递归方法会消耗深度位O(longn)的栈空间,使用归并排序时,应该尽量使用非递归方法。本文实现了java版的非递归归并排序。

更多:数据结构与算法合集

思路分析

  递归排序的核心是merge(int[] arr, int start, int mid, int end)函数,讲[start~mid-1]和[mid~end]部分的数据合并,递归代码是使用递归得到mid,一步步分解数组。

  非递归时,我们直接定义要合并的小数组长度从1开始,在较小的长度数组都合并完成后,令长度*2,继续进行合并,直到合并完成。

完整Java代码

(含测试代码)

  1. public class MergeSort2 {
  2. public void mergeSort(int[] arr) {
  3. if(arr==null || arr.length<=0)
  4. return;
  5. int width = 1;
  6. while(width<arr.length) {
  7. mergePass(arr,width);
  8. width*=2;
  9. }
  10. }
  11.  
  12. private void mergePass(int[] arr,int width) {
  13. int start=0;
  14. while(start+2*width-1<arr.length) {
  15. int mid=start+width-1;
  16. int end=start+2*width-1;
  17. merge(arr,start,mid,end);
  18. start=start+2*width;
  19. }
  20. //剩余无法构成完整的两组也要进行处理
  21. if(start+width-1<arr.length)
  22. merge(arr, start, start+width-1, arr.length-1);
  23. }
  24.  
  25. private void merge(int[] arr, int start, int mid, int end) {
  26. int i=start;
  27. int j=mid+1;
  28. int[] temp = new int[end-start+1];
  29. int index=0;
  30. while(i<=mid && j<=end) {
  31. if(arr[i]<=arr[j])
  32. temp[index++]=arr[i++];
  33. else
  34. temp[index++]=arr[j++];
  35. }
  36. while(i<=mid)
  37. temp[index++]=arr[i++];
  38. while(j<=end)
  39. temp[index++]=arr[j++];
  40.  
  41. for(int k=start;k<=end;k++)
  42. arr[k]=temp[k-start];
  43. }
  44.  
  45. //==========测试代码=================
  46. public void test1() {
  47. int[] a = null;
  48. mergeSort(a);
  49. System.out.println(Arrays.toString(a));
  50. }
  51.  
  52. public void test2() {
  53. int[] a = {};
  54. mergeSort(a);
  55. System.out.println(Arrays.toString(a));
  56. }
  57.  
  58. public void test3() {
  59. int[] a = { 1 };
  60. mergeSort(a);
  61. System.out.println(Arrays.toString(a));
  62. }
  63.  
  64. public void test4() {
  65. int[] a = { 3, 3, 3, 3, 3 };
  66. mergeSort(a);
  67. System.out.println(Arrays.toString(a));
  68. }
  69.  
  70. public void test5() {
  71. int[] a = { -3, 6, 3, 1, 3, 7, 5, 6, 2 };
  72. mergeSort(a);
  73. System.out.println(Arrays.toString(a));
  74. }
  75.  
  76. public static void main(String[] args) {
  77. MergeSort2 demo =new MergeSort2();
  78. demo.test1();
  79. demo.test2();
  80. demo.test3();
  81. demo.test4();
  82. demo.test5();
  83. }
  84. }

  

  1. MergeSort2

更多:数据结构与算法合集

【Java】 归并排序的非递归实现的更多相关文章

  1. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

    上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...

  2. 【Java】快速排序的非递归实现

    快速排序一般采用递归方法(详见快速排序及其优化),但递归方法一般都可以用循环代替.本文实现了java版的非递归快速排序. 更多:数据结构与算法合集 思路分析 采用非递归的方法,首先要想到栈的使用,通过 ...

  3. 归并排序(非递归,Java实现)

    归并排序(非递归):自底向上 public class MergeSort { /** * @param arr 待排序的数组 * @param left 本次归并的左边界 * @param mid ...

  4. Java归并排序的递归与非递归实现

    该命题已有无数解释,备份修改后的代码 平均时间复杂度: O(NLogN)  以2为底 最好情况时间复杂度: O(NLogN) 最差情况时间复杂度: O(NLogN) 所需要额外空间: 递归:O(N + ...

  5. 排序算法练习--JAVA(插入、直接选择、冒泡、快速排序、非递归快速排序)

    排序算法是数据结构中的经典算法知识点,也是笔试面试中经常考察的问题,平常学的不扎实笔试时候容易出洋相,回来恶补,尤其是碰到递归很可能被问到怎么用非递归实现... package sort; impor ...

  6. 面试之路(16)-归并排序详解(MergeSort)递归和非递归实现

    归并排序的概念及定义 归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序是建立 ...

  7. 算法笔记_013:汉诺塔问题(Java递归法和非递归法)

    目录 1 问题描述 2 解决方案  2.1 递归法 2.2 非递归法 1 问题描述 Simulate the movement of the Towers of Hanoi Puzzle; Bonus ...

  8. javascript实现非递归--归并排序

    另一道面试题是实现归并排序,当然,本人很不喜欢递归法,因为递归一般都是没有迭代法好.所以首选都是用迭代法,但是迭代法确实是难做啊,至底而上的思想不好把握. 这是我的实现代码 /* * * 非递归版归并 ...

  9. 自己写算法---java的堆的非递归遍历

    import java.io.*; import java.util.*; public class Main { public static void main(String args[]) { S ...

随机推荐

  1. 学习Spring Boot:(十九)Shiro 中使用缓存

    前言 在 shiro 中每次去拦截请求进行权限认证的时候,都会去数据库查询该用户的所有权限信息, 这个时候就是有一个问题了,因为用户的权限信息在短时间内是不可变的,每次查询出来的数据其实都是重复数据, ...

  2. 在Mac上快速Kill掉Tomcat

    最近IDEA总是会莫名其妙的挂掉,而挂掉之后通过IDEA开启的Tomcat却没有同步给关掉,等我再在IDEA里要启动的时候,就不行了.... 这时,就需要手动去kill掉tomcat,每次先 ps - ...

  3. 解题:九省联考2018 秘密袭击CoaT

    题面 按照*Miracle*的话来说,网上又多了一篇n^3暴力的题解 可能是因为很多猫题虽然很好,但是写正解性价比比较低? 直接做不可做,转化为统计贡献:$O(n)$枚举每个权值,直接统计第k大大于等 ...

  4. token的理解

    今天学习了token,它的英文意思是令牌的意思.在我理解即像通行证一样,在用户登录成功系统后,会为这个用户颁发一个token,这样它去其他系统都免登录,因为有了这个令牌. token的生成我们可以用U ...

  5. java基础基础总结----- 随机数(产生四个随机数)

    前言:在开发的时候经常会遇见,一些验证码登录,其实这些东西,很简单.我曾经开发过一个验证码登录的页面,那时用的插件.但是作为一个合格的开发者,要了解其内部的核心知识,有些东西,可以不深入了解,但是要做 ...

  6. Kubernetes Service

    目录 基本概念 服务发现与负载均衡 配置Service 创建一个ClusterIP类型的Service 创建一个指定ClusterIP的Service 创建一个headless service 创建一 ...

  7. 「Django」contenttypes基本用法

    当一张表和多个表ForeignKey关联,并且多个FK中只能选择其中一个或其中n个时,可以利用contenttypes,只需定义三个字段就搞定! contenttypes 是Django内置的一个应用 ...

  8. SqlParameter防止SQL注入

    SQL注入的解决方案有好几种,待我细细研究过之后逐一讲解. 方法一:SqlParameter方法 这里有一篇博客是详细介绍SqlParameter的,可以看看 点我 string sqlStr=&qu ...

  9. 第一篇:打造专属开发工具Eclipse篇

    第一篇:打造专属开发工具Eclipse篇 eclipse 优化 1.动画很酷,但如果可以的话,我总是在所有的工具中禁用动画.所以classic或者window classic主题是我最常用的主题 , ...

  10. Jad查看源码

    需要者两个文件:下载地址:http://pan.baidu.com/s/11qq4I 1,解压jar包 有两个文件 分别是net.sf.jadclipse_3.3.0 jad.exe 文件 2,找到m ...