算法原理

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

算法思路

  1. 把长度为n的输入序列分成两个长度为n/2的子序列
  2. 对这两个子序列分别采用归并排序
  3. 将两个排序好的子序列合并成一个最终的排序序列

代码实现

 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
import java.util.Arrays;

class MergeSort{
    public static void merge(int[] arr,int left ,int mid, int right) {
        int [] tmp=new int[right-left+1];
        int i=left;// i是第一段序列的下标
        int k=0;// k是临时存放合并序列的下标
        int j=mid+1;// j是第二段序列的下标
        // 扫描第一段和第二段序列,直到有一个扫描结束
        while(i<=mid && j<=right){
             // 判断第一段和第二段取出的数哪个更小,将其存入合并序列,并继续向下扫描
            if(arr[i] < arr[j]){
                tmp[k++]=arr[i++];
            }else{
                tmp[k++]=arr[j++];
            }
        }
        // 若第一段序列还没扫描完,将其全部复制到合并序列
        while(i<=mid){
            tmp[k++]=arr[i++];
        }
        // 若第二段序列还没扫描完,将其全部复制到合并序列
        while(j<=right){
            tmp[k++]=arr[j++];
        }
        k=0;
        while(k <tmp.length){
            arr[k+left]=tmp[k++];// 将合并序列复制到原始序列中
        }
    }
    public static void mergeSort (int [] arr,int left,int right) {
        if(arr.length==0 || left>=right){
            return;
        }
        int mid=(left+right)>>>1;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid+1, right);
        merge(arr, left, mid, right);
        
    }
    public static void main(String[] args) {
        int arr[] = { 51, 46, 20, 18, 65, 97, 82, 30, 77, 50 };
        mergeSort(arr, 0, arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
}

算法分析

最佳情况:T(n) = O(n) 最差情况:T(n) = O(nlogn) 平均情况:T(n) = O(nlogn)

参考文章

https://www.cnblogs.com/guoyaohua/p/8600214.html

https://cuijiahua.com/blog/2017/12/algorithm_4.html