快速排序的原理以及c++实现

快速排序(Quicksort)

什么是快速排序?

快速排序(Quicksort),是对冒泡排序算法的一种改进,基本思想是基于分治法,就是把一个数组或者数据集分成两个部分(L1,L2)同时从数据集中任取一个元素pivot,使L1的部分小于pivot,使L2部分大于pivot,最后将pivot放入最终的位置上。
如图:
快速排序的过程

快速排序的好处

它是大部分内排序算法中平均速度最快的算法,时间复杂度为O(n2),虽然时间复杂度是O(n2),但是一般很少会达到这种情况(这种情况有且只有初始的排序基本有序或者基本逆序才会出现),所以平均来算快速排序算法还是一个效率很高的算法。

快速排序的示例(通过人工运算)

假设一开始序列{xi}是:5,3,7,6,4,1,0,2,9,10,8。
此时,ref=5,i=1,j=10,从后往前找,第一个比5小的数是x8=2,因此序列为:2,3,7,6,4,1,0,5,9,10,8。

此时i=1,j=8,从前往后找,第一个比5大的数是x3=7,因此序列为:2,3,5,6,4,1,0,7,9,10,8。

此时,i=3,j=8,从第8位往前找,第一个比5小的数是x7=0,因此:2,3,0,6,4,1,5,7,9,10,8。

此时,i=3,j=7,从第3位往后找,第一个比5大的数是x4=6,因此:2,3,0,5,4,1,6,7,9,10,8。

此时,i=4,j=7,从第7位往前找,第一个比5小的数是x6=1,因此:2,3,0,1,4,5,6,7,9,10,8。

此时,i=4,j=6,从第4位往后找,直到第6位才有比5大的数,这时,i=j=6,ref成为一条分界线,它之前的数都比它小,之后的数都比它大,对于前后两部分数,可以采用同样的方法来排序。

如何实现快速排序

快速排序主要的实现是通过递归调用,得到pivot后就将其从pivot分为两个区域,之后对两个区域分别使用快速排序算法,直到递归到只有一个数或者为空时为止,此时就代表排序完成。

/**
快速排序的基本实现模板

*/
void QuickSort(ElemType A[],int low,int high){
  if(low<high){  //递归跳出的条件
          int pivotpos = Partition(A,low,high); // pivotpos为自己顶的中值点
          QuickSort(A,low,pivotpos-1);  //对L1进行递归排序
          QuickSort(A,pivotpos+1,high);  //对L2进行递归排序
}
}

完整代码

#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int q[N];
int n;
void quick_line(int q[],int l,int r)/*q[]数组
                                      l 区间内的第一个值的位置
                                      r 区间内最后一个值的位置*/
{
/**
这里把排序过程以及递归调用合并到了一起,
也可以选择分开分成两个函数这样算法就有更好的可读性
*/
    if(l>=r)return;
    int x = q[(r+l)/2],i = l-1,j = r+1;
    while(i<j)
    {
    do i++;while(q[i]<x);
    do j--;while(q[j]>x);
    if(i<j)swap(q[i],q[j]);
    }
    quick_line(q,l,j);
    quick_line(q,j+1,r);
}

int main()
{

    scanf("%d", &n);
    for(int i;i<n;i++) scanf("%d", &q[i]);
    quick_line(q , 0 , n-1);

    for (int i = 0; i < n; i ++ ) printf("%d ",q[i]);

    return 0;
}

注意事项

不是所有的算法都是可以一股脑使用的,当我们需要处理基本有序的数据集的时候就不需要用到快速排序这类算法浪费时间,具体问题具体分析。快速排序中的pivot也不是一定指定中间的数或者是数组的第一个数,而是可以随机选定,代码中给予的方法是为了方便理解。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂派爱丽丝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值