排序算法(2)—— 归并排序、快速排序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012292754/article/details/83869603
稳定 原地排序 时间复杂度 空间复杂度
归并排序 O(n logn) O(n)
快速排序 O(n logn)

1 归并排序

归并排序的合并函数,在合并两个有序数组为一个有序的时,需要借助额外的存储空间

public class MergeSort {

    // n 是数组的大小
    public static void mergeSort(int[] a, int n) {
        mergeSortInternally(a, 0, n - 1);
    }

    private static void mergeSortInternally(int[] a, int p, int r) {
        //递归终止
        if (p >= r) return;

        //取p 到 r 之间的中间位置,防止(p+r) 的和超过 int类型的最大值
        int q = p + (r - p) / 2;

        //分治递归
        mergeSortInternally(a, p, q);
        mergeSortInternally(a, q + 1, r);

        //将 A[p...q] 和 A[q+1...r] 合并为A[p...r]
        merge(a, p, q, r);
    }

    private static void merge(int[] a, int p, int q, int r) {
        int i = p;
        int j = q + 1;
        int k = 0;

        int[] tmp = new int[r - p + 1];// 大小和 a[p...r] 一样的数组

        while (i <= q && j <= r) {
            if (a[i] <= a[j]) {
                tmp[k++] = a[i++];
            } else {
                tmp[k++] = a[j++];
            }
        }

        //判断哪个子数组中有剩余的数据
        int start = i;
        int end = q;
        if (j <= r) {
            start = j;
            end = r;
        }

        //将剩余的数据拷贝到 tmp
        while (start <= end) {
            tmp[k++] = a[start++];
        }

        //将 tmp 中的数组考回 a[p...r]
        for (i = 0; i <= r - p; ++i) {
            a[p + i] = tmp[i];
        }
    }

}

2 快速排序

public class QuickSort {

    //n 数组的大小
    public static void quickSort(int[] a, int n) {
        quickSortInternally(a, 0, n - 1);
    }

    private static void quickSortInternally(int[] a, int p, int r) {
        if (p >= r) return;

        int q = partition(a, p, r); //获取分区点
        quickSortInternally(a, p, q - 1);
        quickSortInternally(a, q + 1, r);
    }

    private static int partition(int[] a, int p, int r) {
        int pivot = a[r];
        int i = p;
        for (int j = p; j < r; ++j) {
            if (a[j] < pivot) {
                int temp = a[i];
                a[i] = a[j];
                a[j] = temp;
                ++i;
            }
        }

        int tmp = a[i];
        a[i] = a[r];
        a[r] = tmp;

        System.out.println("i = " + i);
        return i;
    }

}

3 两者的区别

  • 归并的处理过程是由下到上,先处理子问题,然后再合并;
  • 快排是由上到下,先分区,再处理子问题

猜你喜欢

转载自blog.csdn.net/u012292754/article/details/83869603