排序算法-归并排序
归并排序
归并排序介绍:
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer) 策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
归并排序思想示意图 1-基本思想:
- 归并排序思想示意图 2-合并相邻有序子序列:
再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将
[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤
归并排序的应用实例:
给你一个数组, val arr = Array(8, 4, 5, 7, 1, 3, 6, 2 ), 请使用归并排序完成排序。
代码演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | package com.xuge.sort; import java.util.Arrays; /** * author: yjx * Date :2022/5/3021:22 **/ public class MergeSort { 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)); } 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); } } /** * @param arr 数组 * @param left 左边索引 * @param mid 中间索引 * @param right 右边索引 * @param temp 中转数组 */ public static void merge( int [] arr, int left, int mid, int right, int temp[]) { int i = left; //初始化i,左边有序序列初始索引 int j = mid + 1 ; //初始化j,右边有序序列初始索引 int t = 0 ; //指向temp数组的当前索引 //1.先把左右两边数据填充到temp数组 //直到左右两边有序序列,有一边处理为止 while (i <= mid && j <= right) { //继续执行 //如果左边有序序列小于等于右边有序序列当前元素拷贝到temp中 if (arr[i] < arr[j]) { temp[t] = arr[i]; t += 1 ; i += 1 ; } else { //反之 右边有序序列当前元素拷贝到temp中 temp[t] = arr[j]; t += 1 ; j += 1 ; } } //2.把有剩余的一方剩余数据全部一次填充到temp while (i <= mid) { //说明左边有序序列剩余 temp[t] = arr[i]; t += 1 ; i += 1 ; } while (j <= right) { //说明右边有序序列剩余 temp[t] = arr[j]; t += 1 ; j += 1 ; } //3.将temp数组元素拷贝到arr t = 0 ; int tempLeft = left; System.out.println( "tempLeft=" +tempLeft+ ",right=" +right); while (tempLeft<=right){ //第一次合并 arr[tempLeft]=temp[t]; t+= 1 ; tempLeft+= 1 ; } } } |
速度测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 arr2[] = new int [ 8000000 ]; for ( int i = 0 ; i < 80000 ; i++) { arr2[i] = ( int ) (Math.random() * 800000000 ); //生成随机数[0,80000000); } int temp[]= new int [arr2.length]; System.out.println( "====输出数组=====" ); Date data = new Date(); SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); String str = sdf.format(data); System.out.println( "排序前的时间是:" + str); //23 mergeSort(arr2, 0 , arr2.length- 1 , temp); Date data2 = new Date(); String str2 = sdf.format(data2); System.out.println( "排序后的时间是" + str2); //25 } |