八大排序算法~归并排序

一、基本介绍

归并排序(MERGE- SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治( divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案”修补”在一起,即分而治之)。

 说明:
可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。分阶段可以理解为就是递归拆分子序列的过程。

 代码实现:

import java.util.Arrays;

//归并排序
public class MergeSort {
    public static void main(String[] args) {
        int[] array = {8,4,5,7,1,3,6,2};
        int[] temp = new int[array.length];
        getMergeSort(array,0,array.length-1,temp);
        System.out.println("归并排序后:"+Arrays.toString(array));
    }
    //分+合的方法
    public static void getMergeSort(int[] array,int left,int right,int[] temp){
        if(left < right){
            int middle = (left + right) / 2;   //中间索引
            //向左递归分解
            getMergeSort(array,left,middle,temp);
            //向右递归分解
            getMergeSort(array,middle+1,right,temp);
            //到合并
            merge(array,left,middle,right,temp);
        }

    }
    //合并方法
    /*
    * int[] array  :要排序的原始数组
    * left:   左边有序序列的初始索引
    * middle:  中间索引
    * right:  右边索引
    * int[] temp:  用来做中转的数组
    * */
    public static void merge(int[] array,int left, int middle,int right,int[] temp) {
        int i = left;     //左边有序序列的初始索引
        int j = middle+1; //右边有序序列的初始索引
        int t = 0;        //指向中转数组temp当前索引

        //1.先把左右两边的数据按照规则填充到temp,
        //直到左右两边的有序序列有一边处理完毕为此
        while(i <= middle && j <= right){  //继续
            //如果左边有序序列的指向元素小于等于右边有序序列的指向元素,就将元素给中转数组temp
            if(array[i] <= array[j]){
                temp[t] = array[i];
                t++;
                i++;
            }else {   //如果左边有序序列的指向元素大于右边有序序列的指向元素,就将右边元素给中转数组temp
                temp[t] = array[j];
                t++;
                j++;
            }
        }
        //2.把有剩余数据的一边的数据一次全部填充到temp
        while (i <= middle){   //左边的有序序列还有剩余元素,就全部填充到temp
            temp[t] = array[i];
            t++;
            i++;
        }
        while (j <= right){   //右边的有序序列还有剩余元素,就全部填充到temp
            temp[t] = array[j];
            t++;
            j++;
        }
        //3.将temp数组的元素拷贝到array
        //注意:并不是每次拷贝所有
        t = 0;
        int tempLeft = left;
        while(tempLeft <= right){
            array[tempLeft] = temp[t];
            t++;
            tempLeft++;
        }
    }
}

结果展示:

速度测试:

    public static void main(String[] args) {
        int[] array = new int[8000000];
        for(int i = 0; i < 8000000; i++){
            array[i] =(int) (Math.random() * 8000000);   //生成一个[0,10000)数
        }
        int[] temp = new int[array.length];
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS");
        String data1Str = simpleDateFormat.format(date1);
        System.out.println("排序前的时间:"+data1Str);

        getMergeSort(array,0, array.length-1,temp);
        Date date2 = new Date();
        String data2Str = simpleDateFormat.format(date2);
        System.out.println("排序后的时间:"+data2Str);
    }

 结果:8000000万个数据只需不到2秒

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值