1、递归与非递归对比
递归排序中需要将序列中的所有记录扫描一遍,所以耗费了O(n)时间,而由完全二叉树的深度可知,整个归并排序需要进行,由于归并排序在归并过程中需要与原始记录序列同样数量的存储空间存放归并结果以及递归时深度为
的栈空间,因此空间复杂度为O[n+logn]。在排序过程中,需要两两比较没有发生跳转,所以是一种稳定的排序算法。
非递归的迭代方法,避免了递归时深度为的栈空间,所以空间复杂度为O[n],并且在一定的时间性能上有所提升。
2、非递归大致流程图
3、非递归代码
import java.lang.reflect.Array;
import java.util.Arrays;
public class Main {
public static void MergeSort(int[] array) {
int n = array.length;
//用于存放临时排序数组
int[] tr = new int[n];
//第一次分块,块内长度为1
int k = 1;
while(k < n) {
MergePass(array, tr, k, n);
//每次偶数增加,如上图所示
k *= 2;
MergePass(tr, array, k, n);
k *= 2;
}
}
public static void MergePass(int[] SR, int[] TR, int s, int n) {
// TODO Auto-generated method stub
int i = 1;
int j;
//判断条件:i为每次块内排序起始地址,增长速度为块长加i+2*s(s为块长),2*s代表没两块相排序
//当i的起始位置超出n-2*s+1(最后一块的起始位置)总块数时,将退出循环
while(i <= n-2*s+1) {
Merge(SR, TR, i, i+s-1, i+2*s-1);
i = i + 2 * s;
}
//当只剩最后两大块的时候,将这两块合并
if (i < n-s+1) {
Merge(SR, TR, i, i+s-1, n);
} else {
//或者非排序最后两块,存在单个排序,则将剩余序列加入到TR数组里面
for (j = i-1; j < n; j++) {
TR[j] = SR[j];
}
}
}
/**
* 块内排序,合并操作
* @param trt
* @param tro
* @param s
* @param m
* @param tm
*/
private static void Merge(int[] trt, int[] tro, int s, int m, int tm) {
// TODO Auto-generated method stub
int i = s-1;
int j = m;
int mid = m - 1;
int k = s-1;
int t = tm - 1;
while (i <= mid && j <= t) {
if (trt[i] < trt[j]) {
tro[k++] = trt[i++];
} else {
tro[k++] = trt[j++];
}
}
while (i <= mid) {
tro[k++] = trt[i++];
}
while (j <= t) {
tro[k++] = trt[j++];
}
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7,8,0,9};
MergeSort(array);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}