【数据结构与算法】快速排序

快速排序算法实现及原理分析
Input
5
1 3 2 5 4
Output
1 2 3 4 5
算法原理

  对于a[0,n)数组元素的排序,通过分治思想转化为a[0,m)和a[m+1,n)的排序问题,程序中采用递归实现。
  假设需要排序的区间为[l,r),升序排列。在递归调用前需要选择数组中的一个元素作为参考标准(记为pivot),将小于pivot的元素放在区间左边,大于pivot的元素放在区间右边,区间范围从[l,r)逐渐缩小。首先考虑右侧,从r开始向前找到比pivot小的元素,将该元素放入当前区间左侧(l位置);左侧从l开始向后找到比pivot大的元素,将该元素放入当前区间右侧(r位置)。重复上述过程直到l>=r。
  在选取参考元素的同时,需要记录参考元素的数值,因为在上述的操作中,参考元素原先的位置会被新的数字覆盖。同时最后当l>=r时需要将参考元素的位置放在重合处(l或r)。

#include<iostream>
#include<random>
using namespace std;
int n;
int partition(int *a,int l,int r)
{
    //cout<<"**********"<<endl;
    //cout<<l<<" "<<r<<endl;
    //for (int i=0;i<n;i++)
    //  cout<<a[i]<<" ";
    //cout<<endl;
    int num=l+rand() % (r-l);
    int t=a[l];
    a[l]=a[num];
    a[num]=t;//这里随机选取参考元素,并将参考元素与区间左端点交换
    r--;
    int pivot=a[l];
    while (l<r){
        while (l<r && pivot<=a[r]) r--;
        a[l]=a[r];
        while (l<r && a[l]<=pivot) l++;
        a[r]=a[l];
    }
    a[l]=pivot;
    //for (int i=0;i<n;i++)
    //  cout<<a[i]<<" ";
    //cout<<endl<<"**********"<<endl;
    return l;
}
void qsort(int *a,int l,int r){
    if (r-l<2) return;
    int m=partition(a,l,r);
    qsort(a,l,m);
    qsort(a,m+1,r);
}
int main(){
    cin>>n;
    int *a=new int[n];
    for (int i=0;i<n;i++)
        cin>>a[i];
    qsort(a,0,n);
    for (int i=0;i<n;i++)
      cout<<a[i]<<" ";
    return 0;
}
快排中间过程输出
**********
0 5
1 3 2 5 4
4 3 2 1 5
**********
**********
0 4
4 3 2 1 5
1 2 4 3 5
**********
**********
2 4
1 2 4 3 5
1 2 3 4 5
**********
1 2 3 4 5
时间复杂度分析

  对于每一个分治区间的排序,每次与选取的参考元素比较过程实际上遍历了整个区间 [ l , r ) [l,r) [l,r),而 r − l < n r-l<n rl<n,所以用时不超过 O ( n ) O(n) O(n)
  由于分治的数量在理想情况下为 l o g n log n logn级别,所以总的时间复杂度 O ( n l o g n ) O(nlog n) O(nlogn)。但是由于每次划分的随机性,导致递归的层数可能会达到n,所以最坏情况下时间复杂度为 O ( n 2 ) O(n^2) O(n2)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值