快排思想:
    待排序数组nums[], 每一趟排序前随机选出锚点元素nums[i],该趟排序后,满足条件X:nums[i]左侧和右侧的元素分别小于和大于nums[i]。logn趟后,所有nums[i]数组元素均满足条件X,即排序完成。

    算法框架:
    1、sort
    2、partition

    1、单路快排
    sort(nums, 0, n) :
    start -> 0
    end -> n
    while (start != end) {
    partitionIdx -> partition(nums, start, end);
    sort(nums, start, partitionIdx);
    sort(nums, partitionIdx, end);
    }

    每一趟排序的目的:找到满足条件X的下标index,并用nums[i] -> nums[index]。nums[i]的作用:存放比nums[i]大或者小的数组元素。

    令pivot->nums[size - 1],从i=0开始往后找到第一个值大于pivot的元素时,此时下标为unmatchIdx,即nums[unmatchIdx] > pivot,此时nums[0, unmatchIdx - 1]均满足条件X,将unmatchIdx指向的空间作为存储下一个小于pivot值的空间,由于令pivot覆盖nums[size - 1],并不会丢失pivot信息,此时仅需要从pivot指向的元素的下标开始往前找到第一个值小于pivot的元素nums[k],并令nums[k] -> nums[unmatchIdx],更新unmatchIdx -> k。

    重复以上步骤直到i = k,此时i为存放pivot的位置,即nums[0, i-1] <= nums[i] <= nums[i + 1, size - 1]。

    选取nums[i]的门道:
    1、nums[0]
    2、nums[size - 1]
    3、nums[random], random -> [0, size - 1]

    【存在的问题】
    1、数组有序时,pivot选头尾元素,会导致分隔后>pivot和2、数组重复元素占多数时,重复元素会集中在<=pivot或>=pivot的区间内,导致分隔结果不平衡,如下图所示:
    image.png
    随机选择pivot可解决问题1,双路快排可解决问题2

    2、双路快排
    增加一个变量j,当i从左往右遍历数组时,碰到不符合小于V的数时停止,然后j从数组的右边开始遍历,碰到属于大于V的数时停止,此时我们只需要交换一下i.j指向的数据就可以了,然后重复i扫描,j扫描,交换两个数的操作,即使i和j所指向的数据相等时(都等于V)也会进行交换一次,防止了大量等于V的数据全部推到一边去了。
    image.png
    3、三路快排