Java学习——数据结构——归并排序

学习尚硅谷韩顺平老师的Java数据结构笔记,详情请移步网站

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

  2. 基本思想
    Java学习——数据结构——归并排序_第1张图片

  3. 合并相邻有序子序列
    再来看看治阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将
    [4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤
    Java学习——数据结构——归并排序_第2张图片

package com.Sort;

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

/**
 * 归并排序
 */
public class MergeSort {
    public static void main(String[] args) {
        //int[] arr ={8, 4, 5, 7, 1, 3, 6, 2};

        int arrSize = 80000;//定义数组大小
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//时间格式化
        int[] arr = createNumbers(arrSize);
        int[] temp = new int[arr.length];

        Date start = new Date();//开始时间
        System.out.println("开始: " + simpleDateFormat.format(start));

        mergeSort(arr,0,arr.length-1,temp);

        Date end = new Date();//结束时间
        System.out.println("结束: " + simpleDateFormat.format(end));

        //System.out.println("归并排序:" + Arrays.toString(arr));
    }

    /**
     * 分+合
     * @param arr 原始数组
     * @param left 左边索引
     * @param right 右边索引
     * @param temp 中间数组
     */
    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;
        int j = mid +1;
        int t = 0;//中间数组的索引

        //第一步:把左右两边的数据按照规则填充到中间数组,直到有一边处理完成
        while (i <= mid && j <= right){
            //左边的数据小于右边的数据
            if (arr[i] <= arr[j]){
                temp[t] = arr[i];
                i++;
            }else {//左边的数据大于右边的数据
                temp[t] = arr[j];
                j++;
            }
            t++;
        }

        //第二步:把有剩余的数据填充到中间数组
        while (i <= mid){//左边有剩余
            temp[t] = arr[i];
            t++;
            i++;
        }
        while (j <= right){//右边有剩余
            temp[t] = arr[j];
            t++;
            j++;
        }

        //第三步:将temp数组的元素拷贝到原始数组,注意,并不是每次都拷贝所有
        t = 0;
        int tempLeft = left;
        while (tempLeft <= right){
            arr[tempLeft] = temp[t];
            t++;
            tempLeft++;
        }
    }

    //生成随机数数组
    public static int[] createNumbers(int arrSize) {
        int arr[] = new int[arrSize];
        for (int i = 0; i < arrSize; i++) {
            arr[i] = (int) (Math.random()*8000000);//生成一个0到8000000的数
        }
        return arr;
    }
}

你可能感兴趣的:(Java,算法,java)