[Know] sort merge sort (recursive and non-recursive)

Merge sort ideas

1, the elements to be sorted into two

2, for the left and right halves elements were split again, until you can no longer split

3, to split off and combined elements reorder

4, after the merger of the array after the array is the sort of final

Merge sort understanding

Merge sort complete binary tree sorting applied idea of ​​the array are arranged in layers with divided equally divided form as a complete binary tree, then each element of check points starting from the bottom, were pooled up layer by layer, until again and to an ordered array, complete the entire ordering process.

Merge sort Complexity

Since the merge sort using a complete binary tree form, depending on the complexity of the binary tree understood, the time taken for the O (logn), and merge sort is necessary to trip the adjacent elements pairwise merge that all the elements to be sorted to be scanned again, the time complexity is O (n), therefore, the merge sort total time complexity is O (nlogn).

Because of the need to merge sort the same magnitude and the original data storage space to store the result of merging, and a depth of recursion logn space station, and therefore, the merge sort space complexity is O (n + logn).

Merge sort Features

Since the merge sort requires pairwise comparison, comparative embodiment jumping does not exist, merge sort is a stable sorting algorithm.

To sum up, merge sort is a relatively take up memory space, but efficient and stable sorting algorithm.

Merge sort JAVA implementation

Recursive

public static void main(String[] args) {
        int[] arr = {2, 56, 2, 13, 54, 23, 1};
        mergeSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    private static void merge(int[] arr, int left, int mid, int right) {
        int[] temp = new int[right - left + 1];
        // p1是左半边指针
        int p1 = left;
        // p2是右半边指针
        int p2 = mid + 1;
        // 合并后数组指针
        int k = 0;
        while (p1 <= mid && p2 <= right) {
            if (arr[p1] < arr[p2]) {
                temp[k++] = arr[p1++];
            } else {
                temp[k++] = arr[p2++];
            }
        }
        while (p1 <= mid) {
            temp[k++] = arr[p1++];
        }
        while (p2 <= right) {
            temp[k++] = arr[p2++];
        }
        for (int i = 0; i < temp.length; i++) {
            arr[left + i] = temp[i];
        }
    }

    private static void mergeSort(int[] arr, int start, int end) {
        if (start < end) {
            int mid = (start + end) / 2;
            mergeSort(arr, start, mid);
            mergeSort(arr, mid + 1, end);
            merge(arr, start, mid, end);
        }
    }
}

Non-recursive

public class Main {
    public static void main(String[] args) {
        int[] arr = {2, 56, 2, 13, 54, 23, 1};
        mergeSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    private static void mergeSort(int[] arr) {
        // 使用非递归方式实现归并排序
        int len = arr.length;
        int k = 1;
        while (k < len) {
            mergePass(arr, k, len);
            k *= 2;
        }
    }

    private static void mergePass(int[] arr, int k, int n) {
        int i = 0;
        // 从前往后走,将2个长度为k的子序列合并为1个
        while (i < n - 2 * k + 1) {
            merge(arr, i, i + k - 1, i + 2 * k - 1);
            i += 2 * k;
        }
        // 这段代码保证了,讲那些落单的长度不足两两merge的部分和前面merge起来
        if (i < n - k) {
            merge(arr, i, i + k - 1, n - 1);
        }
    }

    private static void merge(int[] arr, int left, int mid, int right) {
        int[] temp = new int[right - left + 1];
        // p1是左半边指针
        int p1 = left;
        // p2是右半边指针
        int p2 = mid + 1;
        // 合并后数组指针
        int k = 0;
        while (p1 <= mid && p2 <= right) {
            if (arr[p1] < arr[p2]) {
                temp[k++] = arr[p1++];
            } else {
                temp[k++] = arr[p2++];
            }
        }
        while (p1 <= mid) {
            temp[k++] = arr[p1++];
        }
        while (p2 <= right) {
            temp[k++] = arr[p2++];
        }
        for (int i = 0; i < temp.length; i++) {
            arr[left + i] = temp[i];
        }
    }
}

With source code: https://github.com/bruceq/leetcode.git

Published 60 original articles · won praise 57 · views 80000 +

Guess you like

Origin blog.csdn.net/qixinbruce/article/details/103899611