题目
给定你一个长度为 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;
}
部分代码分析
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会一直--发生越界。
该文章介绍了如何使用C++实现快速排序算法,强调了在实现过程中do...while循环与while循环的区别,并讨论了为什么不能将比较条件改为<=的原因,以避免边界问题导致的死循环。
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=快速排序及边界问题分析
3977

被折叠的 条评论
为什么被折叠?



