数据结构与算法系列 -- 归并排序

       归并排序的核心思想还是蛮简单的。如果要排序一个数组,我们先把数组从中间分成前后两
部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有
序了。
 如下图,针对数组:11、   8、   3、  9、7、1、2、5,归并排序的过程如下
 
   
                                                         
伪代码如下:
 


void test(){

 merge_sort(data,0,data.length-1)

}



//对  数组data 下标为 r 到 q 进行排序
void  merge_sort(data,r,q){
   if(r>=q)
        return;

  int mid = (r + q)/2
  merge_sort(data,r,mid)
  merge_sort(data,mid+1,q)
  merge(data,r,mid,mid+1,q)



}

//将已经有序的 data[r1] ... data[q1] ,  data[r2] ... data[q2] ,合并排序为有序数组
void  merge(data,r1,q1,r2,q2){


}

  Java代码如下:

public class SortTest {

    private void swap(int[] data,int i,int j){
           int tmp = data[i];
           data[i] = data[j];
           data[j] = tmp;
    }

    public void printArray(int[] data){
        for(int d:data){
            System.out.print(d+" ");
        }
        System.out.println();
    }

  
    /**
     * 归并排序
     */
    public void mergeSort(int[] data,int r1,int q1,int r2,int q2){
        int start1 = r1;
        int start2 = r2;
        int start  = 0;
        int[] tmp = new int[q2-r1+1];
        while (start1<=q1 && start2 <=q2){
            if(data[start1] <= data[start2]){
                tmp[start++] = data[start1++];
            }else {
                tmp[start++] = data[start2++];
            }
        }

        while (start1<=q1){
             tmp[start++] = data[start1++];
        }

        while (start2<=q2){
            tmp[start++] = data[start2++];
        }

        for(int i=r1;i<=q2;i++){
            data[i] = tmp[i-r1];
        }

    }

    public void merge(int[] data,int r,int q){
        if(r>=q)
            return;

        int middle = (r+q)/2;
        merge(data,r,middle);
        merge(data,middle+1,q);
        mergeSort(data,r,middle,middle+1,q);

    }
    /**
     * 归并排序
     */
    @Test
    public void test4(){
        int[]  data = {55,76,34,66,22,31,13,25,90,87,56,65,66};
        //int[]  data = {6,7,8,9,1,2,30,40,50};
        //mergeSort(data,0,3,4,8);
        merge(data,0,data.length-1);
        printArray(data);

    }
}

结果:

 

13 22 25 31 34 55 56 65 66 66 76 87 90 

 

 

分析:

第一,归并排序是稳定的排序算法吗?
归并排序稳不稳定关键要看
merge() 函数,也就是两个有序子数组合并成一个有序数组的那部分代码。
我们可以控制该函数在合并时,保证相同值元素 的先后顺序不变。所以,归并排序是一个稳定的排序算法。
 
第二,归并排序的时间复杂度是多少?
从我们的原理分析和伪代码可以看出,归并排序的执行效率与要排序的原始数组的有序程度
无关,所以其时间复杂度是非常稳定的,不管是最好情况、最坏情况,还是平均情况,时间
复杂度都是 O(nlogn)。
 
第三,归并排序的空间复杂度是多少?
归并排序的时间复杂度任何情况下都是 O(nlogn),看起来非常优秀。(待会儿你会发现,
即便是快速排序,最坏情况下,时间复杂度也是 O(n 2 )。)但是,归并排序并没有像快排那
样,应用广泛,这是为什么呢?因为它有一个致命的“弱点”,那就是归并排序不是原地排
序算法。
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值