归并排序(非递归,Java实现)

Posted GoldArowana   &

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了归并排序(非递归,Java实现)相关的知识,希望对你有一定的参考价值。

归并排序(非递归):

public class MergeSort {
    /**
     * @param arr   待排序的数组
     * @param left  本次归并的左边界
     * @param mid   本次归并的中间位置,也就是分界线
     * @param right 本次归并的右边界
     * @param <T>   泛型
     * @local aux   辅助空间(Auxiliary Space)
     */
    private static <T extends Comparable<? super T>> void merge(T[] arr, int left, int mid, int right) {
        T[] aux = java.util.Arrays.copyOfRange(arr, left, right + 1);

        int i = left;
        int j = mid + 1;

        for (int t = left; t <= right; t++) {
            if (i > mid) {
                arr[t] = aux[j++ - left];
            } else if (j > right) {
                arr[t] = aux[i++ - left];
            } else if (aux[i - left].compareTo(aux[j - left]) < 0) {
                arr[t] = aux[i++ - left];
            } else {
                arr[t] = aux[j++ - left];
            }
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {
        int n = arr.length;
        for (int size = 1; size < n; size *= 2) {
            for (int i = 0; i < n - size; i += size * 2) {
                merge(arr, i, i + size - 1, Math.min(i + 2 * size - 1, n - 1));
            }
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    private static void printArr(Object[] arr) {
        for (Object o : arr) {
            System.out.print(o);
            System.out.print("\t");
        }
        System.out.println();
    }

    public static void main(String args[]) {
        Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};
        printArr(arr);//3   5   1   7   2   9   8   0   4   6
        sort(arr);
        printArr(arr);//0   1   2   3   4   5   6   7   8   9
    }
}

归并排序(非递归)优化:

merge前判断是否有必要进行归并

public class MergeSort {
    /**
     * @param arr   待排序的数组
     * @param left  本次归并的左边界
     * @param mid   本次归并的中间位置,也就是分界线
     * @param right 本次归并的右边界
     * @param <T>   泛型
     * @local aux   辅助空间(Auxiliary Space)
     */
    private static <T extends Comparable<? super T>> void merge(T[] arr, int left, int mid, int right) {
        T[] aux = java.util.Arrays.copyOfRange(arr, left, right + 1);

        int i = left;
        int j = mid + 1;

        for (int t = left; t <= right; t++) {
            if (i > mid) {
                arr[t] = aux[j++ - left];
            } else if (j > right) {
                arr[t] = aux[i++ - left];
            } else if (aux[i - left].compareTo(aux[j - left]) < 0) {
                arr[t] = aux[i++ - left];
            } else {
                arr[t] = aux[j++ - left];
            }
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {
        int n = arr.length;
        for (int size = 1; size < n; size *= 2) {
            for (int i = 0; i < n - size; i += size * 2) {
                if (arr[i + size - 1].compareTo(arr[i + size]) > 0) {
                    merge(arr, i, i + size - 1, Math.min(i + 2 * size - 1, n - 1));
                }
            }
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    private static void printArr(Object[] arr) {
        for (Object o : arr) {
            System.out.print(o);
            System.out.print("\t");
        }
        System.out.println();
    }

    public static void main(String args[]) {
        Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};
        printArr(arr);//3   5   1   7   2   9   8   0   4   6
        sort(arr);
        printArr(arr);//0   1   2   3   4   5   6   7   8   9
    }
}

递归排序(非递归)继续优化:对小规模数据使用插入排序

归并排序是对一组一组的数据进行归并。当这一组中的数很少时(暂定为4),使用插入排序。

public class MergeSort {
    /**
     * @param arr   待排序的数组
     * @param left  本次归并的左边界
     * @param mid   本次归并的中间位置,也就是分界线
     * @param right 本次归并的右边界
     * @param <T>   泛型
     * @local aux   辅助空间(Auxiliary Space)
     */
    private static <T extends Comparable<? super T>> void merge(T[] arr, int left, int mid, int right) {
        T[] aux = java.util.Arrays.copyOfRange(arr, left, right + 1);

        int i = left;
        int j = mid + 1;

        for (int t = left; t <= right; t++) {
            if (i > mid) {
                arr[t] = aux[j++ - left];
            } else if (j > right) {
                arr[t] = aux[i++ - left];
            } else if (aux[i - left].compareTo(aux[j - left]) < 0) {
                arr[t] = aux[i++ - left];
            } else {
                arr[t] = aux[j++ - left];
            }
        }
    }

    private static <T extends Comparable<? super T>> void insertionSort(T[] arr, int left, int right) {
        for (int i = left + 1; i <= right; i++) {
            T temp = arr[i];
            int j = i - 1;
            while (j >= left && temp.compareTo(arr[j]) < 0) {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = temp;
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr, int left, int right) {
        int len = arr.length;

        int smallSize = 4;//当规模小于4时采用插入排序

        for (int i = 0; i < len; i += smallSize) {
            insertionSort(arr, i, Math.min(i + smallSize - 1, len - 1));
        }

        for (int size = smallSize; size < len; size *= 2) {
            for (int i = 0; i < len - size; i += size * 2) {
                if (arr[i + size - 1].compareTo(arr[i + size]) > 0){
                    merge(arr, i, i + size - 1, Math.min(i + 2 * size - 1, len - 1));
                }
            }
        }
    }

    public static <T extends Comparable<? super T>> void sort(T[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    private static void printArr(Object[] arr) {
        for (Object o : arr) {
            System.out.print(o);
            System.out.print("\t");
        }
        System.out.println();
    }

    public static void main(String args[]) {
        Integer[] arr = {3, 5, 1, 7, 2, 9, 8, 0, 4, 6};
        printArr(arr);//3   5   1   7   2   9   8   0   4   6
        sort(arr);
        printArr(arr);//0   1   2   3   4   5   6   7   8   9
    }
}

  

以上是关于归并排序(非递归,Java实现)的主要内容,如果未能解决你的问题,请参考以下文章

归并排序(非递归,Java实现)

[ 数据结构 -- 手撕排序算法第六篇 ] 归并排序(下)-- 非递归方法实现

Java集合与数据结构 排序

Java集合与数据结构 排序

Java集合与数据结构 排序

Java集合与数据结构 排序