归并排序

归并排序的时间复杂度为o(nlogn),但它很难用于主存排序,主要问题碍于合并两个排序的表需要使用线性附加内存,在整个算法中还要花费将数据拷贝到临时数组,在将临时数组的数据拷贝到原来的数组,其操作严重放慢了排序的速度

package netease;

/**
 * 归并排序
 * 
 * @author li
 * 
 */
public class MergeSort {
    public static void mSort(int[] num, int[] tmp, int start, int end) {
        if (start < end) {
            int middle = (start + end) / 2;
            mSort(num, tmp, start, middle);
            mSort(num, tmp, middle + 1, end);
            merge(num, tmp, start, middle, end);
        }

    }

    public static void mergeSort(int[] num) {
        if (num == null || num.length == 0) {
            throw new NullPointerException("数组为空");
        }
        int[] tmp = new int[num.length];
        mSort(num, tmp, 0, num.length - 1);
    }

    /**
     * 合并有序数组
     * 
     * @param num
     * @param start
     * @param end
     */
    public static void merge(int[] num, int[] tmp, int leftStart, int middle,
            int rightEnd) {
        int leftEnd = middle;
        int tmpPos = leftStart;
        int rightStart = middle + 1;
        int numElements = rightEnd - leftStart + 1;
        while (leftStart <= leftEnd && rightStart <= rightEnd) {
            if (num[leftStart] < num[rightStart]) {
                tmp[tmpPos++] = num[leftStart++];
            } else {
                tmp[tmpPos++] = num[rightStart++];
            }
        }
        while (leftStart <= leftEnd) {
            tmp[tmpPos++] = num[leftStart++];
        }
        while (rightStart <= rightEnd) {
            tmp[tmpPos++] = num[rightStart++];
        }
        // 将数组拷贝回去
        for (int i = 0; i < numElements; i++, rightEnd--) {
            num[rightEnd] = tmp[rightEnd];
        }

    }

    public static void main(String[] args) {
        int[] num = { 1, 7, 5, 34, 2, 6, 7, 8, 23, 1, 4, 5, 6 };
        mergeSort(num);
        for (int i = 0; i < num.length; i++) {
            System.out.println(num[i]);
        }

    }
}

 

posted @ 2016-04-01 16:27  程序猿进化之路  阅读(86)  评论(0)    收藏  举报