归并排序

在排序算法中快速排序的效率是非常高的,但是还有种排序算法的效率可以与之媲美,那就是归并排序;归并排序和快速排序有那么点异曲同工之妙,快速排序:是先把数组粗略的排序成两个子数组,然后递归再粗略分两个子数组,直到子数组里面只有一个元素,那么就自然排好序了,可以总结为先排序再递归;归并排序:先什么都不管,把数组分为两个子数组,一直递归把数组划分为两个子数组,直到数组里只有一个元素,这时候才开始排序,让两个数组间排好序,依次按照递归的返回来把两个数组进行排好序,到最后就可以把整个数组排好序;

时间复杂度O( nlogn )
归并的时间复杂度分析:主要是考虑两个函数的时间花销,一、数组划分函数mergeSort();二、有序数组归并函数_mergeSort();
_mergeSort()函数的时间复杂度为O(n),因为代码中有2个长度为n的循环(非嵌套),所以时间复杂度则为O(n);
简单的分析下元素长度为n的归并排序所消耗的时间 T[n]:调用mergeSort()函数划分两部分,那每一小部分排序好所花时间则为 T[n/2],而最后把这两部分有序的数组合并成一个有序的数组_mergeSort()函数所花的时间为 O(n);

公式:T[n] = 2T[n/2] + O(n);

公式就不仔细推导了,可以参考下: 排序算法之快速排序及其时间复杂度和空间复杂度里面时间复杂度的推导;

所以得出的结果为:T[n] = O( nlogn )
因为不管元素在什么情况下都要做这些步骤,所以花销的时间是不变的,所以该算法的最优时间复杂度和最差时间复杂度及平均时间复杂度都是一样的为:O( nlogn )

空间复杂度为 O(n)
归并的空间复杂度就是那个临时的数组和递归时压入栈的数据占用的空间:n + logn;所以空间复杂度为: O(n)

代码:
package MergeSort;

public class MergeSort1 {

public static void main(String[] args) {
    int [] arr = {12,4,17,2,7,19,10,32,1,8,9};
    mergeSort(arr);
    print(arr);

}

private static void mergeSort(int[] arr) {
        sort(arr, 0, arr.length - 1);   
}

private static void sort(int[] arr, int left, int right) {
    if(left<right){
        int lmiddle = (left+right)/2;
        sort(arr,0,lmiddle);
        sort(arr,lmiddle+1,right);
        merge(arr,left,lmiddle,right);
    }

}

private static void merge(int[] arr, int left, int lmiddle, int right) {
    //定义一个新的数组
    int[] temArr = new int[arr.length];
    //记录右数组的第一个数的索引
    int rmiddle = lmiddle+1;
    //记录左数组的第一索引
    int temp = left;
    //记录临时数组的索引
    int index = left;
    while(left<=lmiddle&&rmiddle<=right){
        if(arr[left]<arr[rmiddle]){
            temArr[index++]=arr[left++];
        }else{
            temArr[index++]=arr[rmiddle++];
        }
    }
    //将剩余数组存放进去
    while(rmiddle<=right){
        temArr[index++]=arr[rmiddle++];
    }
    while(left<=lmiddle){
        temArr[index++]=arr[left++];
    }
    //将临时数组的值保存到原数组
    while(temp<=right){
        arr[temp]=temArr[temp++];
    }
}

private static void print(int[] arr) {
    for(int i :arr){
        System.out.print(i+"\t");
    }
}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值