归并排序和快速排序的 Java 实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Demorngel/article/details/88546698

归并排序递归版

package sort;

public class MergeSortRecursively {
    public static void mergeSort(int[] array) {
        if (array == null || array.length <= 1)
            return;

        sort(array, 0, array.length - 1);
    }

    private static void sort(int[] array, int left, int right) {
        if (left >= right)
            return;

        int middle = left + (right - left) / 2;
        sort(array, left, middle);
        sort(array, middle + 1, right);
        merge(array, left, middle, right);
    }

    private static void merge(int[] array, int left, int middle, int right) {
        int length = array.length;
        int[] temp = new int[length]; // temp数组用于暂存合并的结果

        for (int i = 0; i < length; i++)
            temp[i] = array[i];

        int index = left, leftIndex = left, rightIndex = middle + 1;

        // 将记录由小到大地放进temp数组
        while (leftIndex <= middle && rightIndex <= right) {
            if (array[leftIndex] <= array[rightIndex])
                temp[index++] = array[leftIndex++];
            else
                temp[index++] = array[rightIndex++];
        }

        // 接下来两个while循环是为了将剩余的元素放到temp数组中
        while (leftIndex <= middle)
            temp[index++] = array[leftIndex++];
        while (rightIndex < right)
            temp[index++] = array[rightIndex++];

        // 将temp数组中的元素写入到待排数组中
        for (int i = 0; i < length; i++)
            array[i] = temp[i];
    }
}

归并排序迭代版

package sort;

public class MergeSortIteratively {
    public static void mergeSort(int[] array) {
        if (array == null || array.length <= 1)
            return;

        sort(array);
    }

    private static void sort(int[] array) {
        int length = array.length;
        int k = 1;

        while (k < length) {
            helper(array, k, length);
            k *= 2;
        }
    }

    // 将数组中的相邻的有k个元素的序列进行归并
    private static void helper(int[] array, int k, int length) {
        int i = 0;

        // 从前往后,将2个长度为k的子序列合并为1个
        while (i < length - 2 * k + 1) {
            merge(array, i, i + k - 1, i + 2 * k - 1);
            i += 2 * k;
        }

        // 这段代码保证了,将那些“落单的”长度不足两两merge的部分和前面merge起来。
        if (i < length - k)
            merge(array, i, i + k - 1, length - 1);
    }

    private static void merge(int[] array, int left, int middle, int right) {
        int length = array.length;
        int[] temp = new int[length]; // temp数组用于暂存合并的结果

        for (int i = 0; i < length; i++)
            temp[i] = array[i];

        int index = left, leftIndex = left, rightIndex = middle + 1;

        // 将记录由小到大地放进temp数组
        while (leftIndex <= middle && rightIndex <= right) {
            if (array[leftIndex] <= array[rightIndex])
                temp[index++] = array[leftIndex++];
            else
                temp[index++] = array[rightIndex++];
        }

        // 接下来两个while循环是为了将剩余的元素放到temp数组中
        while (leftIndex <= middle)
            temp[index++] = array[leftIndex++];
        while (rightIndex < right)
            temp[index++] = array[rightIndex++];

        // 将temp数组中的元素写入到待排数组中
        for (int i = 0; i < length; i++)
            array[i] = temp[i];
    }
}

快速排序

package sort;

public class QuickSort {
    public static void quickSort(int[] array) {
        if (array == null || array.length <= 1)
            return;

        sort(array, 0, array.length - 1);
    }

    public static void sort(int[] array, int left, int right) {
        if (right - left <= 0)
            return;

        int index = partition(array, left, right);
        sort(array, left, index - 1);
        sort(array, index + 1, right);
    }

    public static int partition(int[] array, int left, int right) {
        // 选择第一个值作为基准
        int pivot = array[left];
        while (left < right) {
            while (left < right && array[right] >= pivot) {
                right--;
            }
            if (left < right)
                array[left] = array[right];
            while (left < right && array[left] < pivot) {
                left++;
            }
            if (left < right)
                array[right] = array[left];
        }
        array[left] = pivot;
        return left;
    }
}

测试用例

package sort;

import java.util.Arrays;
import java.util.Random;

public class Main {
    public static void main(String[] args) {
        int[] a1 = new Random().ints(10, 1, 100).toArray();
        QuickSort.quickSort(a1);
        System.out.println(Arrays.toString(a1));

        int[] a2 = new Random().ints(10, 1, 100).toArray();
        MergeSortIteratively.mergeSort(a2);
        System.out.println(Arrays.toString(a2));

        int[] a3 = new Random().ints(10, 1, 100).toArray();
        MergeSortRecursively.mergeSort(a3);
        System.out.println(Arrays.toString(a3));
    }
}

猜你喜欢

转载自blog.csdn.net/Demorngel/article/details/88546698