归并排序详解

排序算法跳转总目录

归并排序

归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

>>思路:
归并排序总体分为两大部分:分:将需要排序的数组分成若干子列(采取递归方式)如:
                                                      [8,9,6,3]
                                        递归:         /         \
                                                  [8,9]        [6,3]          
                                        递归:    /    \        /     \    
                                              [8]     [9]    [6]     [3]

                        治:
                                              [8]     [9]    [6]     [3]
                                                   治             治
                                                 [8,9]         [3,6]
                                                           治
                                                      [3,6,8,9]
                                                      
                        第一次治: [8] 和 [9]           ==》[8,9]
                        第二次治: [6] 和 [3]           ==》[3,6]
                        第三次治: [8,9] 和 [6,3]     ==》[3,6,8,9]
                        治具体分三步:1. 两个子列之间依靠指针进行比较,将结果放于新的数组中
                                   2. 将两个子列中未排序的直接放入新的数组后面
                                     问:为什么可以直接放入?不管顺序吗?
                                     答:因为前面的递归会先将数组分成一个一个的子列,
                                         当一个一个子列进行反复操作的时候,提供给下一次两两比较的子列是有序的
                                  3. 将每次得到的不完整的数组都拷贝到arr数组,直到最后一轮的子列比较后,就得到了顺序数组
 步骤:
 治:
 1. 给三个指针:分别是:第一个子列的从头开始的指针,称,指针1
                       第二个子列的从头开始的指针,称,指针2
                       为辅助数组遍历值的指针,称,指针3
 2. 指针1与指针2对应的数组元素比较,小的用指针3遍历在辅助数组中,同时该指针+1;很明显这里有两种情况
 3. 注意:这里可能会出现一种情况,就是已经比较完了,可是某一组中还有剩余元素,但这些剩余元素是有规律的,所以直接加入;当然也是存在两种情况
 4. 然后就是将辅助数组复制到arr上
代码:
public class MergeSort {
    public static void main(String[] args) {
        int[] arr = RandomArr.randomArr(8, 10);//这是作者写的一个产生随机数组的方法,不必理会
        System.out.println(Arrays.toString(arr));
        int[] temp=new int[arr.length];//归并排序所需要的一个辅助数组
        mergeSort(arr,0,arr.length-1,temp);//调用归并排序
        System.out.println(Arrays.toString(arr));
    }
    public static void mergeSort(int[] arr,int left,int right,int[] temp){
        if (left<right){
            int mid=(left+right)/2;//得到中间的索引
            //向左递归
            mergeSort(arr, left, mid, temp);
            //向右递归
            mergeSort(arr, mid+1, right, temp);
            //调用合并的方法
            merge(arr,left,mid,right,temp);
        }
    }
    public static void merge(int[] arr,int left,int mid,int right,int[] temp){//合并的方法
        int l=left;//第一组的指针
        int r=mid+1;//第二组的指针指针
        int te=0;//辅助数组的指针
        while (l<=mid&&r<=right){
            if (arr[l]<=arr[r]){//比较,将小的放入辅助数组
                temp[te]=arr[l];
                te++;
                l++;
            }else {
                temp[te]=arr[r];
                te++;
                r++;
            }
        }
        while (l<=mid){//将剩余的未填充到temp数组的元素填充
            temp[te]=arr[l];
            te++;
            l++;
        }
        while (r<=right){//将剩余的未填充到temp数组的元素填充
            temp[te]=arr[r];
            te++;
            r++;
        }
        //将临时数组复制到arr上
        te=0;
        int tempLeft=left;//定义一个原数组的指针
        while (tempLeft<=right){
            arr[tempLeft]=temp[te];//将temp的有序序列覆盖在arr上
            te++;
            tempLeft++;
        }
    }

值得一提的是,本人测试了八千万个八万内的数据排序,归并居然比快排快了将近一半的时间

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值