快速排序主要思想是每次操作选一个值使得数组左边的数小于等于这个数,右边的数大于这个数。首先选择一个基准,我的话比较喜欢选数组最左边的元素,然后利用两个指针一个从最左边开始,一个从最右边开始。当右边的指针小于等于基准,则停下。当左边的指针大于基准则停下。此时,右边的大于基准,左边的小于基准,交换两个的值。重复以上操作直到两个指针相遇。此时可以知道相遇位置的左边都小于等于基准,相遇位置的右边都大于基准。
但是相遇的位置呢?
可以这么考虑:因为我们是先移动右指针,只要i<j且它对应的值大于基准就会一直左移。所以它停的位置是小于等于基准的位置。如果这个位置和左指针重合了,那么就停了。
所以最后两个指针听得位置一定是小于等于基准的,也就是由右指针控制的。
了解了这个以后,就需要将第一个位置的值(就是选取的基准的位置值)与左右指针位置的值交换。这样在相遇地方左边的值都小于等于基准,右边的值都大于等于基准。
在递归基准左边的值,递归基准右边的值。
代码如下:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void quicksort(vector<int>& arr,int left,int right){
if(left>=right)return;
int i,j,base;
i = left;j = right;
base = arr[left];//选取基准就是数组最左边的值
while(i<j){
while(arr[j]>base && i<j){//首先从右指针开始遍历,遇到小于等于base的值就停下。
j--;
}
while(arr[i]<=base && i<j){//再从左指针开始比遍历,遇到大于base的值就停下。
i++;
}
if(i<j){
swap(arr[i],arr[j]);
}
}
arr[left] = arr[i];//将第一个位置的值和相遇位置的值交换右边两行也可以写成swap(arr[left],arr[i]);
arr[i] = base;
quicksort(arr,left,i-1);//递归左边的
quicksort(arr,i+1,right);//递归右边的
}
int main(){
vector<int> arr(10);
cout<<"请输入10个数:"<<endl;
for(int i=0;i<10;i++){
cin>>arr[i];
}
quicksort(arr,0,arr.size()-1);
for(int i=0;i<arr.size();i++){
cout<<arr[i]<<'\t';
}
return 0;
}
注意:
当基准选择最左边的数字时,就应该从右边开始搜索,当基准选择最右边的数字的,就应该从左边开始搜索,无论是从小到大还是从大到小排序!