递归与分治策略之快速排序

我在前面的文章中写道:递归与分治策略之线性选择,在其中提到求在一个序列中第k小元素;它实现的算法思想就是利用快速排序的算法思想,那我们现在就一起探讨一下快速排序。

 

快速排序算法也是基于分治策略的一个排序算法,当然还有另外一个归并排序,也是基于分治策略的。其算法思想:对于输入的子数组a[p:r],按一下三个步骤进行排序;

(1)分解:以a[p]为基准元素将a[p:r],划分成3段a[p,q-1],a[q]和a[q+1,r],使a[p,q-1]中任何一个元素不大于a[q],而a[q+1,r]中任何一个元素不小于a[q]。

(2)递归求解:通过递归调用快速排序算法分别对a[p,q-1]和a[q+1,r],进行排序。

(3)合并:由于对a[p,q-1]a[q+1,r]的排序是就地进行的,所以在a[p,q-1]和a[q+1,r]都已排好的序后,不需要执行任何计算。

基于这个思想,可实现快速排序算法如下:

 

int Partition(int low, int high, int a[])
{
    a[0] = a[low];
    int pivotkey = a[low];
    while(low < high)
    {
        while(low < high && a[high] >= pivotkey) high--;
        a[low] = a[high];
        while(low < high && a[low] <= pivotkey) low++;
        a[high] = a[low];
    }
    a[low] = a[0];

    return low;
}

void QiuckSort(int low, int high, int a[])
{
    int pivotloc = 0;
    if(low < high)
    {
        pivotloc = Partition(low, high, a);
        QiuckSort(low, pivotloc-1, a);
        QiuckSort(pivotloc+1, high, a);
    }
}

 

很容易证明,快速排序在平均情况下的时间复杂度是O(nlogn);并且在所有同数量级的排序算法中,其平均性能最好。但是若初始序列是有序或者基本上是有序的,快速排序就蜕化为冒泡排序了。对于上面的快排算法还是有优化的空间。

很容易看到,快速排序算法的性能是取决于划分对称性。通过修改Partition函数,可以设计出采用随机选择的快速排序算法。在快速排序算法的每一步中选择划分基数改为随机的,从而可以期望划分是较对称的。随机化的划分算法可实现如下:

 

int RandomizedPartion(int low, int high, int a[])
{
    int i = Random(low, high);
    swap(a[low], a[i]);
    return Partition(a, p, r);
}


 

 


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值