算法学习-归并排序 MergeSort

本文深入讲解归并排序算法,从思想到实现,通过实例详细解释如何将数组分组并排序合并,最后给出Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

归并排序

思想:把数列中的数字进行分组,直到不能再分,即每组只有一个数字,再把相邻的两组做排序合并,直到所有的组都被合并。

举例:9,7,3,4,2
分组:
第一轮结果{9,7},{3,4,2}
第二轮结果{9},{7},{3},{4,2}
第三轮结果{9},{7},{3},{4},{2}
排序合并:
第一轮结果 {9},{7},{3},{2,4}
第二轮结果 {7,9},{2,3,4}
第三轮结果 {2,3,4,7,9}

应该说思想不难理解。记录下来的主要原因是感慨递归实现时的算法巧妙。
先贴代码吧。

package cn.tx.algorithm.quicksort;

public class Mergesort {

    public static void main(String[] args) {
        int A[] = {10,32,7,99,80,60,40,41,40,40,48};
        int nSize = A.length;
        int B[] = new int[nSize];
        copy(A,B);

        splitAndMerge(B,0,nSize,A);

        for (int i = 0; i < nSize; i++) {
            System.out.print(A[i] + ",");
        }
    }
    //拷贝数组
    static void copy(int[] src,int[] obj)
    {
        int nSize = src.length;
        for (int i = 0; i < nSize; i++) {
            obj[i] = src[i];
        }
    }

    //递归分组、排序
    static void splitAndMerge(int[] src,int nStart,int nEnd ,int[] obj)
    {
        if(nStart >= nEnd - 1)
            return;
        int nMiddle = (nStart + nEnd) / 2;
        //接下来的两个函数的调用,对调了输入是src,obj顺序,这真是太聪明了。
        splitAndMerge(obj,nStart,nMiddle,src);
        splitAndMerge(obj,nMiddle,nEnd,src);
        //因为上述两个递归调用对调了src和obj,所以每次回到外层时src就是里层的obj,保证了数据源总是最新的。
        merge(src,nStart,nMiddle,nEnd,obj);
    }

    //排序
    static void merge(int[] src,int nStart,int nMiddle,int nEnd ,int[] obj)
    {
        int i = nStart;
        int j = nMiddle;

        for(int nIndex = nStart ; nIndex < nEnd; nIndex ++) {
            if(i < nMiddle && (j >= nEnd || src[i] < src[j])) {
                obj[nIndex] = src[i];
                i ++;
            }
            else {
                obj[nIndex] = src[j];
                j ++;
            }
        }
    }
}

前边说写得巧妙的是这个函数:

//递归分组、排序
    static void splitAndMerge(int[] src,int nStart,int nEnd ,int[] obj)
    {
        if(nStart >= nEnd - 1)
            return;
        int nMiddle = (nStart + nEnd) / 2;
        //接下来的两个函数的调用,对调了输入是src,obj顺序,这真是太聪明了。
        splitAndMerge(obj,nStart,nMiddle,src);
        splitAndMerge(obj,nMiddle,nEnd,src);
        //因为上述两个递归调用对调了src和obj,所以每次回到外层时src就是里层的obj,保证了数据源总是最新的。
        merge(src,nStart,nMiddle,nEnd,obj);
    }

我已经写了注释,其他就不赘述了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值