【数据结构】【排序】【交换排序】【快速排序】

快速排序

  • 交换排序
  • 快速排序
  • 算法范例
  • 总结
    • 空间复杂度:
    • 时间复杂度:
    • 稳定性:
    • 确定位置

督促自己学习总结,特用文章的形式记录下来,共同进步

交换排序

根据序列中两个元素的关键字比较结果来对换位置的排序算法

快速排序

基本思想:在待排数组L[1,n]中,任意选取一个元素pivot作为基准,通过一趟排序将待排序表分为两个部分L[1,k-1]和L[k+1,n],使L[1,k-1]所有元素都=pivot,则pivot放在了其最终位置上L(k),这个过程称为一趟【快速排序】。然后分别递归对两个子表重复上述过程,直至每部分只有一个元素或为空为止。

算法范例

//[low, high]
    private static void quickSort(int[] sort, int low, int high) {
        if (low < high) {
            //将sort[low,high]划分满足上述条件的两个子表
            int pivotPos = divide(sort, low, high);//划分,最重要
            quickSort(sort, low, pivotPos - 1);
            quickSort(sort, pivotPos + 1, high);
        }
    }

    //划分数组使得[low,k-1]<[k]<=[k+1,high]
    private static int divide(int[] sort, int low, int high) {
        //选取第一个元素作为基准元素
        int pivot = sort[low];
        System.out.print(Arrays.toString(sort) + " " + low + " " + high + " --> ");
        while (low < high) {
            while (low < high && sort[high] >= pivot)
                high--;
            sort[low] = sort[high];//将比基准小的元素移到左端
            while (low < high && sort[low] <= pivot)
                low++;
            sort[high] = sort[low];//将比基准大的元素移到右端
        }
        sort[low] = pivot;
        System.out.println(Arrays.toString(sort) + " " + low + " " + high);
        return low;
    }
    

范例一:无序数组
[69, 63, 28, 55, 41, 51, 35, 90, 18, 17]
[69, 63, 28, 55, 41, 51, 35, 90, 18, 17] low:0 high:9 --> [17, 63, 28, 55, 41, 51, 35, 18, 69, 90] low:8 high:8
[17, 63, 28, 55, 41, 51, 35, 18, 69, 90] low:0 high:7 --> [17, 63, 28, 55, 41, 51, 35, 18, 69, 90] low:0 high:0
[17, 63, 28, 55, 41, 51, 35, 18, 69, 90] low:1 high:7 --> [17, 18, 28, 55, 41, 51, 35, 63, 69, 90] low:7 high:7
[17, 18, 28, 55, 41, 51, 35, 63, 69, 90] low:1 high:6 --> [17, 18, 28, 55, 41, 51, 35, 63, 69, 90] low:1 high:1
[17, 18, 28, 55, 41, 51, 35, 63, 69, 90] low:2 high:6 --> [17, 18, 28, 55, 41, 51, 35, 63, 69, 90] low:2 high:2
[17, 18, 28, 55, 41, 51, 35, 63, 69, 90] low:3 high:6 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:6 high:6
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:3 high:5 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:3 high:3
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:4 high:5 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:4 high:4
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90]

范例二 有序数组:
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90]
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:0 high:9 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:0 high:0
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:1 high:9 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:1 high:1
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:2 high:9 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:2 high:2
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:3 high:9 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:3 high:3
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:4 high:9 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:4 high:4
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:5 high:9 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:5 high:5
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:6 high:9 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:6 high:6
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:7 high:9 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:7 high:7
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:8 high:9 --> [17, 18, 28, 35, 41, 51, 55, 63, 69, 90] low:8 high:8
[17, 18, 28, 35, 41, 51, 55, 63, 69, 90]
当数组有序时,递归深度最深

总结

空间复杂度:

快速排序的递归调用,需要借助一个递归工作栈来保存每一层递归调用的必要信息,其深度与递归调用的最大深度一致,平均情况下为 O ( log ⁡ 2 n ) O( \log_2 n) O(log2n)

时间复杂度:

O ( n log ⁡ 2 n ) O(n \log_2 n) O(nlog2n)

稳定性:

不稳定性算法,在位置划分的时候两个元素相同时,小于基准元素,位于后面的元素会先交换,他们的相对位置会发生变化。

确定位置

每一趟快速排序都可以确认一个基准元素的最终位置

你可能感兴趣的:(数据结构)