归并排序

2016-10-29  本文已影响7人  zhaoyubetter

归并排序是利用分治的思想,来解决排序问题;
分治法
将原问题分解成若干个规模较小但类似于原问题的子问题,递归的求解这些子问题,然后再合并这些子问题的解来建立原问题的解;

分解:分解待排序的n个元素的序列组成 n/2个元素的2个子序列;
解决:使用归并排序递归地排序2个子序列;
合并:合并2个已排序好的子序列,以产生已排序好的序列;
直到待排序序列长度为1时,递归“回升”;

关键操作是合并2个有序序列的过程:

实现代码(递归形式):

public static void main(String[] args) {
        int a[] = {-10, 20, 0, 3, 90, 5, 2, 1};
        mergeSort(a, 0, a.length - 1);
        System.out.println(Arrays.toString(a));

        System.out.println("===============");
        int b[] = {4, 1};
        merge(b, 0, 0, 1);
        System.out.println(Arrays.toString(b));
    }

    /**
     * 合并操作
     * 子数组:a[low, mid], a[mid+1,high] 都是有序的
     */
    public static void merge(int[] a, int low, int mid, int high) {
        int i = low;            // 第一段序列的下标
        int j = mid + 1;        // 第二段序列的下标
        int k = 0;            // 临时存放合并序列下标

        int[] ta = new int[high - low + 1];        // 临时合并序列
        // 扫描第一段与第二段
        while (i <= mid && j <= high) {
            if (a[i] <= a[j]) {
                ta[k] = a[i];
                i++;
            } else {
                ta[k] = a[j];
                j++;
            }
            k++;
        }

        // 收尾操作
        while (i <= mid) {
            ta[k] = a[i];
            i++;
            k++;
        }
        while (j <= high) {
            ta[k] = a[j];
            j++;
            k++;
        }

        // 将合并序列 复制到原始数组中
        for (k = 0, i = low; i <= high; i++, k++) {
            a[i] = ta[k];
        }
    }

    public static void mergeSort(int[] a, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            // 左边
            mergeSort(a, low, mid);
            // 右边
            mergeSort(a, mid + 1, high);
            // 合并
            merge(a, low, mid, high);
        }
    }

输出:

Paste_Image.png
上一篇下一篇

猜你喜欢

热点阅读