排序算法——快速排序

快速排序分析

描述:

快速排序,又称划分交换排序,简称快排.在平均状况下,排序n个项目要 O ( n lg ⁡ n ) O(n\lg{n}) O(nlgn)次比较。在最坏状况下则需要 O ( n 2 ) O(n^2) O(n2)次比较,但这种状况并不常见。事实上,快速排序 O ( n lg ⁡ n ) O(n\lg{n}) O(nlgn)通常明显比其他算法更快,因为它的内部循环可以在大部分的架构上很有效率地达成。
排序算法——快速排序_第1张图片

代码如下:

/**
* 快排升序
*
* @param array 待排序数组
* @param low   开始下标
* @param high  结束下标
*/
public static void quickSortAscend(int[] array, int low, int high) {
    if (high > low) {
        int partition = randomizedPartitionAscend(array, low, high);
        quickSortAscend(array, low, partition - 1);
        quickSortAscend(array, partition + 1, high);
    }
}
/**
* 分区(划分)方法  升序
*
* @param array 待分区数组
* @param low   开始下标
* @param high  结束下标
* @return 分区(划分)点
*/
private static int randomizedPartitionAscend(int[] array, int low, int high) {
    int i = low;
    //随机选择partition位置
    int p = random(low, high);
    exchange(array, p, high);
    for (int j = low; j < high; j++) {
        if (array[high] > array[j]) {
            exchange(array, j, i);
            i++;
        }
    }
    exchange(array, i, high);
    return i;
}

算法分析:

与归并排序类似,快排使用了分治思想,分治过程:

分解: array[low…high]被划分为两个(可能为空)子数组array[low…p-1]和array[p+1…high],其中,array[low…p-1]每个元素都小于等于array[p],array[p+1…high]中每个元素都大于等于array[p]。

解决: 递归调用快排,对划分后的子数组array[low…p-1]和array[p+1…high]排序

合并: 子数组是原址排序,不需要合并

性能分析:

快排的运行时间依赖于子数组的划分是否平衡,而子数组划分的平衡与否又依赖于用于划分的元素。

  1. 最坏情况划分:划分产生的两个子问题分别包含了n-1个元素和0个元素

    划分操作的时间复杂度为 Θ ( n ) \Theta(n) Θ(n)

    对一个0个元素的数组递归调用会直接返回,因此 T ( 0 ) = Θ ( 1 ) T(0)=\Theta(1) T(0)=Θ(1)

    综上算法运行时间的递归式为: T ( n ) = T ( n − 1 ) + T ( 0 ) + Θ ( n ) = T ( n − 1 ) + Θ ( n ) T(n)=T(n-1)+T(0)+\Theta(n)=T(n-1)+\Theta(n) T(n)=T(n1)+T(0)+Θ(n)=T(n1)+Θ(n)。每层递归的代价 Θ ( n ) \Theta(n) Θ(n)累加,共n层,因此 T ( n ) = Θ ( n 2 ) T(n)=\Theta(n^2) T(n)=Θ(n2)

  2. 最好情况划分:两个子数组的规模都不大于n/2

    划分操作的时间复杂度为 Θ ( n ) \Theta(n) Θ(n)

    算法运行时间的递归式为: T ( n ) = 2 T ( n / 2 ) + Θ ( n ) T(n)=2T(n/2)+\Theta(n) T(n)=2T(n/2)+Θ(n)。因此 T ( n ) = Θ ( n log ⁡ n ) T(n)=\Theta(n\log{n}) T(n)=Θ(nlogn)

  3. 平均情况:快排的平均运行时间更接近于最好情况,时间复杂度为 T ( n ) = Θ ( n lg ⁡ n ) T(n)=\Theta(n\lg{n}) T(n)=Θ(nlgn)。为了引入随机性,使算法达到平均情况的性能,在划分子数组时使用随机选取划分点的方法。

你可能感兴趣的:(algorithm)