2.1.4 Merge Sort

思想: 採用Divide and Conquer的做法, 將資料序列分成兩個子序列, 排序每一半, 然後再把排序好的兩個子序列合併成為一個有序的序列.

效率: Merge Sort的時間複雜度是O(nlogn), 主要是複製(因為此演算法通常都不是in-place sorting)跟比較會花比較多時間

package idv.carl.sorting;

import java.util.Arrays;

/**
 * @author Carl Lu
 */
public class MergeSort {

    public static void main(String args[]) {
        MergeSort mergeSort = new MergeSort();
        int[] input = new int[] {4, 8, 10, 1, 5, 9, 7};
        mergeSort.mergeSort(input);
        Arrays.stream(input).forEach(data -> System.out.print(data + " "));
    }

    public void mergeSort(int[] data) {
        int[] temp = new int[data.length];
        doMergeSort(data, temp, 0, data.length - 1);
    }

    private void doMergeSort(int[] data, int[] temp, int from, int to) {
        if (from >= to) {
            return;
        }
        // Step1. Calculate the bound index
        int mid = (from + to) >> 1;
        // Step2. Sort the left part
        doMergeSort(data, temp, from, mid);
        // Step3. Sort the right part
        doMergeSort(data, temp, mid + 1, to);
        // Step4. Merge the two parts
        merge(data, temp, from, mid + 1, to);
    }

    private void merge(int[] data, int[] temp, int from, int mid, int to) {
        // The index for merged data in temp array
        int count = 0;
        // The min index of the left part
        int minLeft = from;
        // The max index of the left part
        int maxLeft = mid - 1;

        // Step1. Get values from left part and compare with the right part
        while (from <= maxLeft && mid <= to) {
            if (data[from] < data[mid]) {
                // If left < right, add the left value into temp
                temp[count++] = data[from++];
            } else {
                // If left > right, add the right value into temp
                temp[count++] = data[mid++];
            }
        }

        // Step2. Handle the remaining part:
        // 2.1 For the left part
        while (from <= maxLeft) {
            temp[count++] = data[from++];
        }
        // 2.2 For the right part
        while (mid <= to) {
            temp[count++] = data[mid++];
        }

        // Step3. Copy the final results from temp array into data array
        for (int i = 0; i < (to - minLeft + 1); i++) {
            data[minLeft + i] = temp[i];
        }
    }

}

原始碼網址點我

Last updated