快速排序 内容详解

序言

虽然快排可以调用函数,但还是需要了解它的本质详解

快速排序之所以比冒泡排序快,是因为其减少交换次数,通过更优的交换方法,达到减少时间的消耗,冒泡排序的时间复杂度在O(n^{^{2}}) ,而快速排序的时间复杂度在O(nlogn) 数据范围在^{10^{5}}内不会超时

内容详解

先随机输入一组数  1-8  6 8 5 4 2 3 1 7

68542317

1.为了能够更高效的进行交换,通常以某个数的基准点,使得在这个数的左边都比它小,右边都比它大,为了方便,以第一个数6为基准点,此时j从右到左 i从左到右(先从右边开始找)依次分别寻找比6小的,比6大的

61542387
ij

2.找到后继续 j++,i++ 找到下一个i对应的数比6大 j比6小, 直到i与j相等 

61542387
i,j

 3.随即将该数与6互换,这样在6左边的数都比6小 在6右边的数都比6大 再将其分为1-5 7-8分别再重复进行上述操作,这里以1-5(同样以第一个数3为基准点)再进行依次操作

31245687
ij

213

4

5687
i,j

4.再看3右边: 操作同理 (结果就不再复述)

21345678

i

j

关于为什么要先从从右边j++开始: 如果先从左边开始,在第二步的操作中,i会抵达8,然后进行6 8的交换,达不到预期效果,所以应当从右边开始,以此来确保i对应的数绝对比基准数要小

代码实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int a[10001];
int n;
void swap(int a1,int b1)    {int w=a[a1];a[a1]=a[b1];a[b1]=w;}  //交换函数
void qsort1(int begin,int end) // 快排的实现
{
    if(begin > end)  return ;  // 退出快排函数 避免出现死循环
    int tem=a[begin];    // 记录基准点
    int i=begin,j=end;
    while(i!=j)
    {
        while(a[j]>=tem && i<j)   j--;  //从右边开始找小于基准点的数
        while(a[i]<=tem && i<j)   i++;  //从左边开始找大于基准点的数
        if(i<j) swap(i,j);    
    }
    a[begin]=a[i]; // 交换基准点和第i个 确保基准点左边全部比其小 右边全部不它大
    a[i]=tem;
    qsort1(begin,i-1);  // 继续分成两个部分进行快速排序
    qsort1(i+1,end);

}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    qsort1(1,n);
    for(int i=1;i<=n;i++) printf("%d ",a[i]);
   // system("pause");
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值