快速排序的核心思想:
- 每一轮选取一个随机的数字作为参照,一般选取本轮的第一个数字,然后设置两个指针,分别指向序列头部和尾部;
- 与参照数字作比较,左边遇到大于参照数字指针停止移动,右边遇到小于参照的数字,指针停止移动;
- 将此时左右两边指针所指的数字交换位置;
- 如此下去,直到左右指针相遇
这样做保证左边的数字总小于参照数字,右边的数字总大于参照数字,每一轮的比较和移动,实际就是为了找到本轮参照数字在排序完成后应该所在的位置。
过程演示
这里选取30做为参照数字
- 左指针指向第一个数54,大于30,停止,右指针移动
2. 59大于30,继续向左移动
-
6小于30,停止,将左右指针所指元素互换
-
互换后,左指针继续向右移动
-
67大于30,左2指针停止,右指针移动
-
64大于30,继续左移
7. 67大于30,右指针向左移动
8. 6小于30 指针停止,下面条件判断发现左右指针早已相遇,跳出循环
9. 最后将参照数字与跳出循环后右指针所指位置的数字互换,至此,30就找到了排序后它应该所在的位置。
这样不断递归后,所有的数字都找到了它排序后应该在的位置上面,于是排序就完成了。
完整代码
c语言
#include<stdio.h>
int partition(int A[],int low ,int high){//获取枢轴下标函数,并调整使得枢轴左边的元素小于枢轴,右边大于枢轴
int povit=A[low];
while(low<high){
while(low<high&&povit<=A[high])high--;
A[low]=A[high];
while(low<high&&povit>=A[low])low++;
A[high]=A[low];
}
A[low]=povit;
return low;
}
void quickSort(int *A,int low,int high){//递归排序
if(low<high){
int pivotpos=partition(A,low,high);
quickSort(A,low,pivotpos-1);//对序列前半部分排序
quickSort(A,pivotpos+1,high);//对序列后半部分排序
}
}
int main(){
int A[11]={0,5,3,6,8,1,9,2,6,7,-2};
int i=0;
quickSort(A,0,10);
for(;i<11;i++){
printf("%d ",A[i]);
}
return 0;
}
结果如下:
时间复杂度与空间复杂度
快速排序最差的情况下时间复杂度为:O( n^2 ),退化为冒泡排序
不适用于本来有序的情况
平均时间复杂度
快速排序的最优和平均时间复杂度是:O(nlog2n)
最优的情况下空间复杂度为:O(log2n) ;每一次都平分数组的情况
最差的情况下空间复杂度为:O( n ) ;退化为冒泡排序的情况
是不稳定的算法