【Java】 归并排序的非递归实现

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

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

思路分析

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

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

完整Java代码

(含测试代码)

public class MergeSort2 {
	public void mergeSort(int[] arr) {
		if(arr==null || arr.length<=0)
			return;
		int width = 1;
		while(width<arr.length) {
			mergePass(arr,width);
			width*=2;
		}
	}

	private void mergePass(int[] arr,int width) {
		int start=0;
		while(start+2*width-1<arr.length) {
			int mid=start+width-1;
			int end=start+2*width-1;
			merge(arr,start,mid,end);
			start=start+2*width;
		}
		//剩余无法构成完整的两组也要进行处理
		if(start+width-1<arr.length)
			merge(arr, start, start+width-1, arr.length-1);
	}

	private void merge(int[] arr, int start, int mid, int end) {
		int i=start;
		int j=mid+1;
		int[] temp = new int[end-start+1];
		int index=0;
		while(i<=mid && j<=end) {
			if(arr[i]<=arr[j])
				temp[index++]=arr[i++];
			else
				temp[index++]=arr[j++];
		}
		while(i<=mid)
			temp[index++]=arr[i++];
		while(j<=end)
			temp[index++]=arr[j++];

		for(int k=start;k<=end;k++)
			arr[k]=temp[k-start];
	}

	//==========测试代码=================
	public void test1() {
		int[] a = null;
		mergeSort(a);
		System.out.println(Arrays.toString(a));
	}

	public void test2() {
		int[] a = {};
		mergeSort(a);
		System.out.println(Arrays.toString(a));
	}

	public void test3() {
		int[] a = { 1 };
		mergeSort(a);
		System.out.println(Arrays.toString(a));
	}

	public void test4() {
		int[] a = { 3, 3, 3, 3, 3 };
		mergeSort(a);
		System.out.println(Arrays.toString(a));
	}

	public void test5() {
		int[] a = { -3, 6, 3, 1, 3, 7, 5, 6, 2 };
		mergeSort(a);
		System.out.println(Arrays.toString(a));
	}

	public static void main(String[] args) {
		MergeSort2 demo =new MergeSort2();
		demo.test1();
		demo.test2();
		demo.test3();
		demo.test4();
		demo.test5();
	}
}

  

MergeSort2

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

原文地址:https://www.cnblogs.com/yongh/p/9965913.html

时间: 2024-10-06 11:40:44

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

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

上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来探讨一下非递归方案 实验结果令人还是有些失望,原来非递归方案的性能并不比递归方案性能高 代码如下: package com.newflypig.eightqueen; import java.util.Date; /** * 使用循环控制来实现回溯,解决N皇后 * @author [email pr

快速排序 归并排序的非递归版本 备忘

首先,归并排序,分治,递归解决小的范围,再合并两个有序的小范围数组,便得到整个有序的数组. 这是很适合用递归来写的,至于非递归,便是从小到大,各个击破,从而使得整个数组有序.代码如下: void merge(vector<int> &A, int left, int mid, int right) { int i=left,j=mid+1; vector<int> tmp(right-left+1,0); int k=0; while(i<=mid&&

高速排序 归并排序的非递归版本号 备忘

首先,归并排序,分治.递归解决小的范围.再合并两个有序的小范围数组,便得到整个有序的数组. 这是非常适合用递归来写的.至于非递归.便是从小到大.各个击破,从而使得整个数组有序.代码例如以下: void merge(vector<int> &A, int left, int mid, int right) { int i=left,j=mid+1; vector<int> tmp(right-left+1,0); int k=0; while(i<=mid&&a

【书上讲解】归并排序的非递归写法

描述 [题解] 让区间的长度L为1,2,4,...2^(n-1) 然后对每个位置i开始的长度为L的区间归并有序,用归并排序的方法就好,然后i跳转到i+L 复杂度仍然是log2(n)*n级别的,注意写的时候的一些细节. 比如一定要让最后L>=n的情况进行过一次,不然无法保证整个序列是有序的 [代码] /* 归并排序非递归写法 */ #include <cstdio> const int N = 1e5; int a[N+10],b[N+10]; int n; //把a这个数组在l1..r2

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

归并排序(非递归): public class MergeSort { /** * @param arr 待排序的数组 * @param left 本次归并的左边界 * @param mid 本次归并的中间位置,也就是分界线 * @param right 本次归并的右边界 * @param <T> 泛型 * @local aux 辅助空间(Auxiliary Space) */ private static <T extends Comparable<? super T>&g

归并排序的递归与非递归实现java

package com.edu.hpu.sort.merge; import com.edu.hpu.sort.Sort; public class MergeSort extends Sort { @Override public int[] doSort(int[] arr) { return mergeSort2(arr, 0, arr.length - 1); } @SuppressWarnings("unused") private int [] mergeSort(int

归并排序 - 递归非递归实现java

1.归并排序思想: 以2路归并为例,一个有n个记录的序列可以看作n个长度为1的有序子序列,将其两两合并成n/2(向上取整)个长度为2或1的有序序列,当有奇数个记录时为1,重复归并,直到得到一个长度为n的有序序列. 2.归并排序的复杂度: 递归:时间复杂度O(nlongn),空间复杂度O(n+longn) 非递归:时间复杂度O(nlongn),空间复杂度O(n) 所以用到归并排序,还是优先考虑非递归吧.  3.递归实现 1 public void mergeSort1(int[] data){ 2

JAVA递归、非递归遍历二叉树(转)

原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { private char date; private BinTree lchild; private BinTree rchild; public BinTree(char c) { date = c; } // 先序遍历递归 public static void preOrder(BinTree t) {

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi