首页 > 试题广场 >

简要介绍快速排序的实现和时间复杂度。

[问答题]
简要介绍快速排序的实现和时间复杂度。
推荐

一 快速排序采用的思想是分治思想:

快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。

二 伪代码
1.从右边扫描时,记录比基准小的元素的下标j
2.从左边扫描时,记录比基准大的元素的下标i
3.  if(若此时两个下标 i = j){
        当前下标的元素与基准进行交换,结束一次划分
        把原有序列分为两端重新划分
    }
    else{
        执行第四步骤
    }
4.这时开始交换两个下标对应的元素
5.以当前的位置开始,继续从1开始
三 代码示例
 private static int nums[];//待排序的数组
 public static void QuickSort(int low,int high){
    //进行安全性检查
    if(low>=high||nums.length<2){
        return;
    }
    int i = low;//定义左边界
    int j = high;//定义右边界
    int member = nums[low];//以数组的最左边当做 基准
    while(i!=j){
        //从右到左进行扫描,寻找比基准member小的元素,并记录于下标j中
        while(nums[j]>=member && i<j){
            j--;
        }
        //从右到左进行扫描,寻找比基准member大的元素,并记录于下标j中
        while(nums[i]<=member && i<j){
            i++;
        }
        //此时 i j 已经定位到相应的元素的下标
        if(i<j){
            //进行对 i j 下标的元素进行交换
            nums[i] += nums[j];
            nums[j] = nums[i]- nums[j];
            nums[i] = nums[i]- nums[j];
        }
    }
    //一次划分结束
    //当i=j的时候,要把 基准和当前的下标的元素进行交换
    //基准,也就是nums[low]里面放的就是基准元素
    nums[low] += nums[i];//此时i和j相等
    nums[i] = nums[low] - nums[i];
    nums[low] = nums[low] - nums[i];
    //下面分别对基准的左边和右边进行划分
    QuickSort(low,i-1);//对基准的左边进行划分
    QuickSort(i+1,high);//对基准的右边进行划确定分
 }
四 分析

快速排序的时间主要耗费在划分操作上,对长度为k的区间进行划分,共需k-1次关键字的比较。

最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(n*n)

在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(nlgn)

尽管快速排序的最坏时间为O(n2),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂度为O(nlgn)。


编辑于 2015-02-06 15:42:30 回复(0)
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序每次将待排序数组分为两个部分,在理想状况下,每一次都将待排序数组划分成等长两个部分,则需要logn次划分。
而在最坏情况下,即数组已经有序或大致有序的情况下,每次划分只能减少一个元素,快速排序将不幸退化为冒泡排序,所以快速排序时间复杂度下界为O(nlogn),最坏情况为O(n^2)。在实际应用中,快速排序的平均时间复杂度为O(nlogn)。
快速排序在对序列的操作过程中只需花费常数级的空间。空间复杂度S(1)。
但需要注意递归栈上需要花费最少logn最多n的空间。
发表于 2015-01-20 19:25:55 回复(0)