归并排序(两种实现方式,递归和非递归方法)

归并排序是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并

使用递归的方式进行做排序。

import java.lang.reflect.Array;
import java.util.Arrays;

/**
 * java实现归并排序
 * 递归版本的和非递归版本的
 */
public class MergeSortTest {
    public static void main(String[] args) {
        int []arr=new int[]{9, 8, 7, 6, 5, 4, 3, 2, 10  };
        mergesort(arr,0,arr.length-1);
//        System.out.println(Arrays.toString(arr));
        System.out.println(Arrays.toString(arr));
    }

    private static void mergesort(int[] arr, int left, int right) {
        if(left>=right){
            return;
        }
        int mid=left+(right-left)/2;
        mergesort(arr,left,mid);
        mergesort(arr,mid+1,right);
        sort(arr,left,mid,right);
    }

    private static void sort(int[] arr, int left, int mid, int right) {
        int []temp=new int[right-left+1];
        int le=left;
        int ri=mid+1;
        int index=0;
        while((le<=mid)&&(ri<=right)){
            if(arr[le]>arr[ri]){
                temp[index++]=arr[ri++];
            }else{
                temp[index++]=arr[le++];
            }
        }
        while(le<=mid){
            temp[index++]=arr[le++];
        }
        while (ri<=right){
            temp[index++]=arr[ri++];
        }
        for (int i = 0; i < temp.length; i++) {
            arr[i+left]=temp[i];
        }
    }
}

以下是非递归版本的归并排序,非递归的重点在于如何确定并合理的分解待排序数组。

public class NotMergeSortTest {
    public static void main(String[] args) {
        int[] arr = new int[]{9, 8, 7, 6, 5, 4, 3, 2, 10};
        arr = mergeSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    /**
     * 归并排序
     * 非递归版的实现
     * 从切分的数组长度为1开始的,一次归并变回原长度的2倍
     *
     * @param arr
     * @return
     */
    private static int[] mergeSort(int[] arr) {
        int len = 1;
        while (len < arr.length) {
            for(int i=0;i+len<=arr.length;i+=len*2){
                int low=i,mid=i+len-1,high=i+2*len-1;
                if(high>arr.length-1){//当为奇数的时候所做的处理
                    high=arr.length-1;
                }
                merge(arr,low,mid,high);
            }
            len *=2;
        }
        return arr;
    }

    private static void merge(int[] arr, int low, int mid, int high) {
        int[]temp=new int[arr.length];
        int right=mid+1;
        int index=low;
        int begin=low;
        while(low<=mid&&right<=high){
            if (arr[low]>=arr[right]){
                temp[index++]=arr[right++];
            }else{
                temp[index++]=arr[low++];
            }
        }
        while(low<=mid){
            temp[index++]=arr[low++];
        }
        while(right<=high){
            temp[index++]=arr[right++];
        }
        while(begin<=high){
            arr[begin]=temp[begin++];
        }
    }
}

归并排序比较占用内存,但却是一种效率高且稳定的算法。归并排序的时间复杂度,平均时间复杂度、最坏时间复杂度都为O(nlogn),空间复杂度为T(n)。归并排序算法是稳定性的算法

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值