算法思想:主要是分治
算法步骤概括:
1.对于一个待排序序列,任意从中选择一个数,一般实现的时候会选择序列的第一个数,这个数被称为基准数。
2.将所有小于基准数的数放到基准数右边,所有大于等于基准数的数放到其右边,这样就将基准数以外的数分成了两个子序列。
3.对上述两个子序列重复上述步骤,这样序列会被越分越小,最后排序会完成。
另外,也可以这么理解,基准数就是当前要将其放到正确排序位置的数,而为了将其放到一个正确的位置,有一个函数处理序列将且只能将序列中的一个数放到正确的位置,那么只要对未排序完成的那部分数据序列使用这个函数就行。
基准数不是第一位的情况:基准数和第一位交换就行了
而最核心的部分便是如何将序列中的一个数放到正确的位置,亦即将所有小于基准数的数放到基准数右边,所有大于等于基准数的数放到其右边,将基准数以外的数分成两个子序列。基本思路是使用双指针的方式将数值替换移动。
要强调的是,在本文代码中,采用的是记录然后覆盖基准数,最后确定基准数的位置后再赋值的方式。所以对于本实现方法,如果基准数在左边第一位,应该是先从右向左遍历找一个小于基准数的数替换基准数。当然,如果基准数在右边第一位,应该先从左边遍历找一个大于基准数的数,也可以将基准数与第一位置的数互换,这样还是先从左进行遍历。不过好麻烦,还是默认第一位吧。
void quickSort(int a[],int l,int r) {
int x=a[l],i=l,j=r;//基准数取最左边的
while(i<j) {//确定基准数的位置
while(i < j && a[j] >= x)j--; //从右向左找第一个小于x的数
if(i < j)a[i++] = a[j];//替换序列右边的一个不小于基准值的值
while(i < j && a[i] < x)i++; //从左向右找第一个大于等于x的数
if(i < j)a[j--] = a[i];//替换序列左边的一个大于基准值的值
}
a[i] = x;//基准数确定位置后的赋值
if(l<i-1)quickSort(a,l,i-1);//左子序列不只有一个元素时递归
if(i+1<r)quickSort(a,i+1,r);//右子序列不只有一个元素时递归
}
出口其实就是左子序列和右子序列都是只含有一个元素的时候。