排序算法-归并排序详细图解

归并排序:

采用了分治策略 就是将原问题分解为一些规模较小的相似子问题,然后递归解决这些子问题,最后合并其结果作为原问题的解。

归并的核心思想 将两个有序的数组合并成一个大的有序的数组,通过递归把待排序数组变成完全有序数组。

归并的核心算法就是如何将2个数组合并

算法思想:

将待排序数组一直往下分解直到不可分解为止也就是一个数为一个子数组

然后对这些子数组层层合并(合并里有排序的过程)得到最后的有序数组

分解的过程很简单 就是一直递归向下分解 直到一个元素一组为止

合并原理:

其实就是合并2个有序数组的算法: 

首先要有一个临时数组temp 以及2个索引分别指向2个数组的首地址 让2个索引对应的值进行比较 谁对应的值小 把值小的放入temp 然后当前索引++ 再循环比较 肯定会有一个数组索引先到头 在对另一个数组剩下的元素遍历放入temp即可

然后再把合并好的数组放会原数组对应的为止 就算完成此次合并

以 {3,4,6,10} {2,5,7,8} 为例作图给大家演示下:

两个数组索引对应的值进行比较 小的放进临时数组 索引++ 然后继续比较

       
34610 2578
temp
2       

 

 

       
34610 2578
temp
23      

 

 

       
34610 2578
temp
234     

 

 

       
34610 2578
temp
2345    

 

 

       
34610 2578
temp
23456   

 

       
34610 2578
temp
234567  

 

       
34610 2578
temp
2345678 

 

此时 其中一个数组索引已经到头了 然后直接对另一个数组剩余元素进行遍历放入temp即可

可能有些童鞋会有疑问为什么剩下的直接放进去就行?

因为2个数组都是有序数组 此数组当前索引对应的值比另一个数组最大值都大 此数组剩余元素值肯定大于另一个数组而且还是从小到大排列的 所以直接放入temp就可以了麻

temp
234567810

 

动图展示:

算法代码:

public class Sort {
    public static void main(String[] args) {
        int[] a={10,4,6,3,8,2,5,7};
        //归并排序
        mergeSort(a,0,a.length-1);
    }

    private static void mergeSort(int[] a, int left, int right) {
        if(left<right){
            int middle = (left+right)/2;
            //对左边进行递归
            mergeSort(a, left, middle);
            //对右边进行递归
            mergeSort(a, middle+1, right);
            //合并
            merge(a,left,middle,right);
        }
    }

    private static void merge(int[] a, int left, int middle, int right) {
        int[] tmpArr = new int[a.length];
        int mid = middle+1; //右边的起始位置
        int tmp = left;
        int third = left;
        while(left<=middle && mid<=right){
            //从两个数组中选取较小的数放入中间数组
            if(a[left]<=a[mid]){
                tmpArr[third++] = a[left++];
            }else{
                tmpArr[third++] = a[mid++];
            }
        }
        //将剩余的部分放入中间数组
        while(left<=middle){
            tmpArr[third++] = a[left++];
        }
        while(mid<=right){
            tmpArr[third++] = a[mid++];
        }
        //将中间数组复制回原数组
        while(tmp<=right){
            a[tmp] = tmpArr[tmp++];
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值