数据结构与算法(第二季):快速排序(Quick Sort)

2022-01-12  本文已影响0人  萧1帅

快速排序(Quick Sort)

一、概念

image image image

二、轴点构造

image image image image image image image image image image

三、代码实现

public class QuickSort<T extends Comparable<T>> extends Sort<T> {

    @Override
    protected void sort() {
        sort(0, array.length);
    }

    /**
     * 对 [begin, end) 范围的元素进行快速排序
     * @param begin
     * @param end
     */
    private void sort(int begin, int end) { 
        if (end - begin < 2) return; //至少有两个元素才执行快速排序

        // 确定轴点位置 O(n),并进行一次快速排序
        int mid = pivotIndex(begin, end);
        // 对子序列进行快速排序
        sort(begin, mid); 
        sort(mid + 1, end); 
    } 

    /**
     * 构造出 [begin, end) 范围的轴点元素,并进行一次快速排序
     * @return 轴点元素的最终位置
     */
    private int pivotIndex(int begin, int end) {
        // 为了降低最坏情况(O(n^2)的时间复杂度)的出现概率,随机选择一个元素跟begin位置进行交换
        swap(begin, begin + (int)(Math.random() * (end - begin)));

        // 备份begin位置的元素
        T pivot = array[begin];
        // end指向最后一个元素
        end--;

        // 如果begin == end 则退出排序
        while (begin < end) {
            while (begin < end) {
                if (cmp(pivot, array[end]) < 0) { // 右边元素 > 轴点元素
                    end--; // 只位移,不进行元素交换
                } else { // 右边元素 <= 轴点元素
                    array[begin++] = array[end];
                    break; //执行完一次操作后,需要掉头,所以执行一个break
                }
            }
            while (begin < end) {
                if (cmp(pivot, array[begin]) > 0) { // 左边元素 < 轴点元素
                    begin++;
                } else { // 左边元素 >= 轴点元素
                    array[end--] = array[begin];
                    break; // 通过两个break,能实现两个while交替执行。
                }
            }
        }

        // 将轴点元素放入最终的位置
        array[begin] = pivot;
        // 返回轴点元素的位置
        return begin;
    }
}
复制代码
image image

四、时间复杂度

image
上一篇 下一篇

猜你喜欢

热点阅读