14. 归并排序以及性能测试

1. 什么是归并排序?

  • 天下大势,合久必分,分久必合
    在这里插入图片描述

2. 归并排序的思想

在这里插入图片描述

在这里插入图片描述

3. 代码实现,以及性能测试

package com.qin.sort;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

//n个数据排n-1次,他是线性阶
public class MergerSort {
    public static void main(String[] args) {

        //创建一个数组
        int[] arr = {8,4,5,7,1,3,6,2};
        int[] temp = new int[arr.length]; //归并排序需要额外的空间开销
        mergeSort(arr,0,arr.length-1,temp);
        System.out.println("归并排序后"+ Arrays.toString(arr));
        //性能测试
        int[] arr1 = new int[80000];
        int[] temp1 = new int[arr1.length];
        for (int i = 0; i < 80000; i++) {
            arr1[i] = (int)(Math.random()*80000000);
        }
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format1 = simpleDateFormat.format(date1);
        mergeSort(arr1,0,arr1.length-1,temp1);
        Date date2= new Date();
        String format2 = simpleDateFormat.format(date2);
        System.out.println("运行前"+format1);
        System.out.println("运行后"+format2);
    }



    //分+合的方法
    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);
        }
    }

    //合并的方法
    //arr 原始数组 ,left 左边有序序列的初始索引,mid中间
    //right 右边索引 ,temp 中转数组
    public static void merge(int [] arr,int left,int mid,int right,int[] temp){
        //System.out.println("xxxxx");
        int i = left;  //初始化i,左边有序序列的初始索引
        int j = mid + 1; //初始化j,右边有序序列的初始索引
        int t = 0; //指向临时数组的下标

        //先把左右两边(有序)的数据,按规则填充到temp数组,知道左右两边的有序序列有一边处理完毕为止
        while (i<=mid && j<=right){
            //判断左边与右边的数谁大
            if (arr[i]<=arr[j]){ //左边的数大于右边的数
                temp[t] = arr[i];
                i++; //后移
                t++; //后移
            }else {
                temp[t] = arr[j]; //左边大于等于
                j++;
                t++;
            }
        }

        //把有剩余数据的一边的数据,依次全部填充到temp,
        while (i<=mid){   //说明左边的有序序列还有剩余的元素
            temp[t] = arr[i];
            i++;
            t++;
        }
        while (j<=right){
            temp[t] = arr[j];
            j++;
            t++;
        }

        //重点,很难理解
        //将我们的temp数组拷贝到arr原数组
        //注意并不是,每次都拷贝8个
        t = 0;
        int tempLeft = left;
        //System.out.println("tempLeft="+tempLeft+"right="+right);
        while (tempLeft<=right){  //其实第一次合并 tempLeft = 0; right = 1;
            arr[tempLeft]  = temp[t]; //第二次    tempLeft = 2; right = 3;
            t++;
            tempLeft++;
        }
    }
}



  • 结果,以及性能测试
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值