二路归并非递归排序Java实现

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]);
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值