重温基础算法内部排序之快速排序法

Posted 顧棟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重温基础算法内部排序之快速排序法相关的知识,希望对你有一定的参考价值。

内部排序之快速排序法

文章目录


对冒泡排序的一种优化

主要思想

快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。

通过一趟排序将待排记录分割成独立的两个部分,一部分的关键字比另一部分的关键字小,则可以分别对两部分记录继续进行排序。

  1. 选取任务选取的一个记录,作为枢轴或(支点)(pivot)
  2. 重新排列记录,所有关键字比pivot值小的摆放在pivot前面,所有关键字比pivot值大的摆在pivot的后面(相同的数可以到任一边)。在这个分区退出之后,该pivot就处于数列的中间位置。这个称为分区(partition)操作;
  3. 重复执行步骤2。把小于pivot关键字的子数列和大于pivot关键字的子数列排序。

过程演示

JAVA代码

package sort;

public class QuickSort 

    private static int count = 1;

    public static void main(String[] args) 
        int[] o = 49, 38, 45, 27, 46, 13, 27, 8;
        System.out.print("排序前: ");
        for (int t : o) 
            System.out.print(t);
            System.out.print(" ");
        
        System.out.println();

        // 算法部分
        int left = 0;
        int right = o.length - 1;

        quickSort(o, left, right);

        System.out.print("排序后: ");
        for (int t : o) 
            System.out.print(t);
            System.out.print(" ");
        
        System.out.println();

    

    private static void quickSort(int[] arr, int left, int right) 
        if (left < right) 
            int partitionIndex = partition(arr, left, right);
            quickSort(arr, left, partitionIndex - 1);
            quickSort(arr, partitionIndex + 1, right);
         else 
            count++;
        
    

    private static int partition(int[] arr, int left, int right) 
        // left位置的记录就是pivot,index代表比pivot小的下标
        int index = left + 1;
        System.out.print("第" + count + "趟pivot=" + arr[index - 1] + ",排序后: ");

        for (int i = index; i <= right; i++) 
            if (arr[i] < arr[left]) 
                swap(arr, i, index);
                index++;
            
        
        swap(arr, left, index - 1);
        for (int t : arr) 
            System.out.print(t);
            System.out.print(" ");
        
        System.out.println();
        count++;
        return index - 1;
    

    private static void swap(int[] arr, int i, int j) 
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    

执行结果

排序前: 49 38 45 27 46 13 27 8 
第1趟pivot=49,排序后: 8 38 45 27 46 13 27 49 
第2趟pivot=8,排序后: 8 38 45 27 46 13 27 49 
第4趟pivot=38,排序后: 8 27 27 13 38 45 46 49 
第5趟pivot=27,排序后: 8 13 27 27 38 45 46 49 
第8趟pivot=45,排序后: 8 13 27 27 38 45 46 49 
排序后: 8 13 27 27 38 45 46 49 

算法分析

时间复杂度分析

经过上述一趟快速排序,我们只确定了一个元素的最终位置,我们最终需要经过 n n n趟快速排序才能将一个含有 n n n个数据元素的序列排好序,下面我们来分析其时间复杂度.

n n n 为待排序数组中的元素个数, T ( n ) T(n) T(n)为算法需要的时间复杂度则
T ( n ) = D ( 1 ) n ≤ 1 D ( n ) + T ( I 1 ) + T ( I 2 ) n > 1 T(n)= \\begincases \\vcenter D(1) &n \\leq 1 \\\\ D(n)+T(I_1)+T(I_2) &n >1 \\endcases T(n)=D(1)D(n)+T(I1)+T(I2)n1n>1
其中 D ( n ) = n − 1 D(n)=n−1 D(n)=n1 ,是一趟快排需要的比较次数,一趟快排结束后将数组分成两部分 I 1 I_1 I1 I 2 I_2 I2

最好时间复杂度

最好的情况是,每一次划分都正好将数组分成长度相等的两半
T ( n ) = D ( 1 ) n ≤ 1 D ( n ) + T ( n 2 ) + T ( n 2 ) n > 1 T(n)= \\begincases D(1) & n \\leq 1 \\\\ D(n)+T(\\fracn2)+T(\\fracn2) &n >1 \\endcases T(n)=D(1)D(n)+T(2n)+T(2n)n1n>1

∴ T ( n ) = D ( n ) + 2 T ( n 2 ) = D ( n ) + 2 D ( n 2 ) + 2 T ( n 4 ) . . . = D ( n ) + 2 D ( n 2 ) + 4 D ( n 4 ) + . . . + 2 k D ( n 2 k ) = n − 1 + 2 ( n 2 − 1 ) + 4 ( n 4 − 1 ) + . . . + 2 k ( n 2 k − 1 ) = ( n − 1 ) + ( n − 2 ) + ( n − 4 ) + . . . + ( n − 2 k )    ⟹    ∑ k = 1 n n − 2 k = k n − 2 k + 1 ∵ k = l o g 2 n ∴ 原式 = n l o g 2 n − 2 n + 1    ⟹    O ( n l o g 2 n ) \\beginaligned \\therefore T(n)&=D(n)+2T(\\fracn2) \\\\ &=D(n)+2D(\\fracn2)+2T(\\fracn4) \\\\ &.\\\\ &.\\\\ &.\\\\ &=D(n)+2D(\\fracn2)+4D(\\fracn4)+...+2^kD(\\fracn2^k) \\\\ &=n-1+2(\\fracn2-1)+4(\\fracn4-1)+...+2^k(\\fracn2^k-1) \\\\ &=(n-1)+(n-2)+(n-4)+...+(n-2^k) \\\\ &\\implies \\displaystyle \\sum_k=1^n n-2^k=kn-2^k+1 \\\\ &\\because k=log_2^n\\\\ &\\therefore 原式=nlog_2^n-2n+1 \\implies \\boxedO(nlog_2^n)\\\\ \\endaligned T(n)=D(n)+2T(2n)=D(n)+2D(2n)+2T(4n)...=D(n)+2D(2n)+4D(4n)+...+2kD(2kn)=n1+2(2n1)+4(4n1)+...<

以上是关于重温基础算法内部排序之快速排序法的主要内容,如果未能解决你的问题,请参考以下文章

重温基础算法内部排序之冒泡排序法

重温基础算法内部排序之归并排序法

重温基础算法内部排序之归并排序法

重温基础算法内部排序之希尔排序法

重温基础算法内部排序之基数排序法

重温基础算法内部排序之基数排序法