算法 第四版---2.2归并排序

导读:

归并排序:是采用分治法(Divide and Conquer)。
它的主要思想就是把两个数组(各个一定要有序),归并在一个数组中。
如一个数组要求用归并进行排序,主要要考虑试实现两个部分:
(1)“分解”——如何将一个大的数组逐步分成多个小的有序数组。
(2)“合并”—— 如何将两个有序列表并成一个适当的数组。
则可以两种进行归并:
1. 自顶而下的归并排序
2. 自底而上的归并排序
核心代码:

//归并
    public static void merge(Comparable[]a , int lo, int mid, int hi){
        //把a的lo-hi复制到aa中,这里未必a的开始结束的引索是从0,到 最后一个索引,用一个辅助数组(必不可少)把要归并数组的复制,此时的数组a[lo,mid], a[mid+1,hi]已经有序。可以进行归并。
        Comparable[] aa = new Comparable[a.length];
        for(int k = lo; k<=hi; k++){
            aa[k] = a[k];
        }

        //在辅助数组aa中分  左  中   右引索。
        int i = lo;//左半开始
        int j = mid +1;//由半开始

        //其实是对对应的数据lo--hi索引元素拷贝
        for(int k =lo; k<=hi; k++){
        //分别为4种情况 如图
            if(i>mid)
                a[k] = aa[j++];
            else if(j>hi)
                a[k] = aa[i++];
            else if(less(aa[i],aa[j]))
                a[k] = aa[i++];//aa[i]更小
            else
                a[k] = aa[j++];
        }

    }

归并中,比较复制的数组示意图:
这里写图片描述

1. 自顶而下的归并排序
示意图:
自顶而下

分---直到单个元素为止。然后 逐步合并。
    public static void sort(Comparable[] a, int lo,  int hi){
    //排除错误数组  和 (1)终止递归,出口
        if(hi<=lo) return;
        //(2)规律
        int mid = lo+(hi-lo)/2;
        //(3)递归方法
        sort(a,lo,mid);
        sort(a,mid+1,hi);
        merge(a ,  lo,  mid,  hi);

    }

自底而上

public static void sort(Comparable[] a){
        //步长为1,然后是2,然后是4
        for(int sz = 1; sz < a.length; sz = sz+sz){
            //内层是从 第一个元素开始,从步长为1(肯定形成有序)开始,元素0 ,1 为一组。 每次循环移动变化为0--->2, 则2,3为一组。规律:0---2;2--4;即:lo+=sz+sz;直到起始元素为a.length-sz,因为它不够归并的。
            for(int lo = 0;lo<a.length-sz;lo+=sz+sz){
                //lo+sz-1 中间  Math.min(lo+sz+sz-1, a.length-1) 最边,但不能超出a.length-1。
                merge(a,lo,lo+sz-1,Math.min(lo+sz+sz-1, a.length-1));
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值