基础算法-快速排序-AcWing 785. 快速排序

题目

给定你一个长度为 n 的整数数列。

请你使用快速排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式

输入共两行,第一行包含整数 n。

第二行包含 n 个整数(所有整数均在 1∼10e9 范围内),表示整个数列。

输出格式

输出共一行,包含 n 个整数,表示排好序的数列。

数据范围

1≤n≤100000

输入样例:

5
3 1 2 4 5

输出样例:

1 2 3 4 5

 思路

使用快排模版 

代码 

#include <bits/stdc++.h>

using namespace std;

//const int Max = 10e9+10;

void QuickSort (int *a ,int l, int r){
    if(l >= r) return; //递归终止条件
    
    int i = l-1 ,j = r+1 ,x = a[ (l+r) >> 1 ];
    while(i < j){
        do i++ ; while( a[i] < x);
        do j-- ; while( a[j] > x);
        //不能设为">=“,不能用while
        if( i < j ) swap(a[i], a[j]);
    }
    QuickSort(a, l, j);
    QuickSort(a, j+1, r);
}

int main(){
    
    int n;
    scanf("%d", &n);//数组个数
    int a[n+1];
    for(int i = 0; i < n; i++){
        scanf("%d", &a[i] );
    }//输入数组
    
    QuickSort(a, 0, n-1); //调用函数进行快排
    
    for(int i = 0; i < n; i++){
        printf("%d", a[i] );
        if(i != n-1) printf(" ");
    }//输出数组
    

    return 0;
}

 参考博客:https://blog.youkuaiyun.com/weixin_45636061/article/details/124077136?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168386092516782427420906%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168386092516782427420906&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-124077136-null-null.142^v87^control_2,239^v2^insert_chatgpt&utm_term=快速排序及边界问题分析icon-default.png?t=N3I4https://blog.youkuaiyun.com/weixin_45636061/article/details/124077136?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168386092516782427420906%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168386092516782427420906&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-124077136-null-null.142^v87^control_2,239^v2^insert_chatgpt&utm_term=快速排序及边界问题分析​​​​​​​

部分代码分析

1. 使用 do····while,而不是用 while 

while(i < j){
        do i++ ; while( a[i] < x);
        do j-- ; while( a[j] > x);

        if( i < j ) swap(a[i], a[j]);
    }
while(i < j){
        while( a[i] < x) i++ ;
        while( a[j] > x) j--;

        if( i < j ) swap(a[i], a[j]);
    }

 

两者的不同点在于do····while是先执行,再判断-->等价于前置运算。

do i++; while(q[i] < x);
do j--; while(q[j] > x);
//等价于
while(q[++i] < x);
while(q[--j] > x);

而while是先判断再执行,i 指针指向不小于 x的数会停下来,而 j 指针指向不大于x数会停下来,来进行交换后再判断。

即此时的 a[ i ] >= x , a [ j ] <= x;

交换后的 a [ i ] <= x , a[ j ] >= x , 对于 do···while 直接 i ++ ; j ++;,而 while 要先判断,若a [i ] < x

可以 i ++; 若 a [i ] == x ,就不能 i ++;若( a [ i ] == x &&  a [ j ] == x ),就导致  一直 停滞,死循环。

那能不能 将 while 中的判断条件中的 “ < ” 改为 "<=" ( a[ i ] <= x )  

若选取的x是数组里最大的数,序列中所有的数都满足q[i] <= x,会导致i会一直++发生越界都不会停下来。

若选取的x是数组里最小的数,同理q[j] >= x恒成立,j会一直--发生越界。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值