C++快速排序(Quick sort)
一、排序算法
排序算法大体可分为两类:
一种是稳定的排序算法,主要有:冒泡排序,插入排序,归并排序
另一种则是不稳定的排序算法,主要有:选择排序,希尔排序,堆排序,快速排序
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序n个元素要O(nlogn)次比较。在最坏状况下则需要O(n^2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他O(nlogn)算法更快,因为它的内部循环可以在大部分的架构上很有效率地被实现出来。
二、快排思路
1.思路:分治、“挖坑”
- 找一个轴点,把它挖出来存在一个变量中,然后把比轴点小的数放在它左边,比它大的数放在它右边
- 一个区间一个区间地进行递归处理
- 最后当所有区间都仅剩一个数时,排序完成
快速排序是一种不稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动
2.步骤
1.先把a[i]挖出来存在一个临时变量x中
此时a[i] 就已经 空了出来,可以存放一个比x小的数
2.循环开始:(结束条件:i>=j)
- 从当前数组最右端 j 开始遍历,直到找到比x小的数
2. 把a[j]**挖出来**放到a[i]处,i往右移动一格
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200711214822465.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTExODIwMw==,size_16,color_FFFFFF,t_70)
3. 此时 **a[j]** 可以存放 **比x大** 的数
4. 再从当前数组**最左端i**开始遍历,直到找到**比x大**的数
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200711215446546.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTExODIwMw==,size_16,color_FFFFFF,t_70)
5. 把a[i]**挖出来**放到a[j]处,j往左移动一格
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200711215918712.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTExODIwMw==,size_16,color_FFFFFF,t_70)
7. 此时 **a[i]** 可以存放**比x小**的数(回到循环最开始,判断i是否大于等于j)
结束循环
当循环结束后,a[i]是被挖掉的,用它来存放变量x
一轮循环结束后如下图👇
最后进入递归,开始处理以i为轴点的 左区间 和 右区间
三、测试代码
#include<iostream>
using namespace std;
//72 6 57 88 60 42 83 73 48 85
void quickSort(int *arr,int left,int right){
if(left<right){//判断有无坑位
int x = arr[left],i = left,j = right;
while(i<j){
while(j>i && arr[j]>=x) j--;//寻找坑位
//此处一定不要忘了加判断条件if(arr[j]<x)
//不然又可能是j=i而跳出的循环
if(arr[j]<x) arr[i++] = arr[j];//填坑
while(i<j && arr[i]<=x) i++;//寻找坑位
if(arr[i]>x) arr[j--] = arr[i];//填坑
}
arr[i] = x;//填坑
quickSort(arr,left,i-1);//处理左区间
quickSort(arr,i+1,right);//处理右区间
}
}
//测试函数
int main(){
int arr[10] = {72,6,57,88,60,42,83,73,48,85};
for(int i = 0; i < 10;i++)
cout<<arr[i]<<' ';
cout<<endl;
quickSort(arr,0,9);
for(int i = 0; i < 10;i++)
cout<<arr[i]<<' ';
cout<<endl;
return 0;
}
测试结果