我写这篇文章的目的主要是帮助理解快速排序中的一些小细节(大佬请无视),如果你是学过快速排序后对某些代码有些疑问或者想温习一下快速排序,这篇文章应该可以帮到你。文章的代码可能和你掌握的不一样,但原理是一样的。如果你还不知道什么是快速排序的话推荐你看这篇文章(里面10种排序都有,用java实现的)不要一去不复返啊!我也是从这篇文章里学会了多种排序,其他排序的一些细节也会陆陆续续的讲完。当你看的差不多的时候,我想你对某些细节一定有一些困惑,这可能也是我当时的困惑,虽然我不可能和你的困惑完全一样,但我相信大多数人应该都有和我当初差不多的困惑。这也是我写这篇文章的原因。先上完整代码,有注释帮助理解。完整代码后面会再对一些小细节进行分析。
#include<iostream>
using namespace std;
void quicksort(int *arr,int left,int right){
int tmp=arr[left];//用tmp保存arr[left]的值
int i=left;//i指向最左边
int j=right;//j指向最右边
if(i>=j) return ;//递归结束的条件
while(true){
//这下面两行代码会在下面进行详细分析
while(i<=j&&arr[i]<=tmp) i++;
while(i<=j&&arr[j]>=tmp) j--;
if(i>j) break;//i不可能等于j 当然你也可以直接写if(i>=j) break;最终结果不变
//交换arr[i]和arr[j]的值
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
//此时j一定在i的前面原因我下面会解释
arr[left]=arr[j];
arr[j]=tmp;
//此时j这个位置已经放了一个应该放的元素以后不需要变了
quicksort(arr,left,j-1);
quicksort(arr,j+1,right);
}
int main(){
int n;
cin>>n;
int a[199];
for(int i=0;i<n;i++){
cin>>a[i];
}
quicksort(a,0,n-1);
for(int i=0;i<n;i++){
cout<<a[i]<<' ';
}
return 0;
}
while(i<=j&&arr[i]<=tmp) i++;
while(i<=j&&arr[j]>=tmp) j--;
这里为什么i<=j。
理由:1)想一想当arr[i]<=tmp一直成立的话会发生什么呢! i会指向最后一个元素的下一个位置对吧,这应该很好理解,因为此时是i>j使循环退出的,而j指向的是最后一个元素,所以i指向的是最后一个元素的下一个位置。此时j一定在i的前面。
2)当arr[i]<=tmp中途不成立时j是无论如何也不会和i相等的。因为i停下来的话说明arr[i]>tmp,此时若i=j的话相当于arr[j]>tmp,这个时候arr[j]>=tmp这个条件成立j还会继续减1,所以j一定是在i的前面。
接下来看下面这两行代码
arr[left]=arr[j];
arr[j]=tmp;
arr[left]是和arr[j]交换。为什么是和arr[j]交换而不是和arr[i]交换呢原因就和上面的说的一样,i可能指向了一个不该指的位置,这样子就能直接排除掉和i交换了。那为什么arr[left]要和arr[j]交换呢,可以理解为arr[left]的位置为什么在j这个地方。原因很简单因为arr[i]一定在一个不满足arr[i]<=tmp的位置。它的前一个位置就一定满足arr[i]<=tmp;
这是我第一次写文章,不好之处请见谅啊
如果觉得我写的好的欢迎关注我的微信公众号啊