- 选择基准值(Pivot):从数组中选择一个元素作为基准值。(一般选择数组中的最后一个元素)
- 分区操作(Partition):将数组分为两部分,使得左边部分的所有元素都小于等于基准值,右边部分的所有元素都大于基准值。
- 递归排序:对左右两部分分别递归地应用快速排序.
方法一:左右指针法
选择最后的数字作为基准值,定义两个指针分别位于数组的头和尾,先遍历头指针,找到一个大于基准元素的值,之后遍历右指针,找到一个小于基准元素的值,交换两者的值,然后继续循环,直到头指针等于尾指针时停止,最后交换头指针与基准元素,这样单趟排序就完成了.
使用这种方法一定要先遍历左边,这样才能保证最后与基准值交换的值一定是大于基准值的
以下是一趟排序的图解
定义两个指针,并保存最后一个元素的下标
然后左指针先向后遍历找到一个大于5的元素位置
之后遍历右边指针找到一个小于五的元素
交换两个位置的元素
之后继续重复该过程
当两个指针相等时,结束遍历,交换begin和index的元素,就完成了一躺排序
这时五前面的数均小于五,后面的均大于五,单趟排序就完成了
单趟排序代码实现
void Swap(int* a, int* b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int PartSort1(int* a, int begin, int end)
{
while (begin < end)
{
//begin找大
while (begin < end && a[begin] <= a[index])
//一定要取到等于号,否则会陷入死循环,因为不写等于如果碰倒与key相等的就会在原地不动
{
begin++;
}
//end找小
while (begin < end && a[end] >= a[index])
{
end--;
}
Swap(&a[begin], &a[end]);
}
Swap(&a[begin], &a[index]);
return begin;
}
对于注释a[begin] <= a[end]一定要取等号图解
使用递归排序所有元素
使用递归分别对基准值左右的元素进行排序
递归图解如下
递归代码实现
void QuickSort(int* a, int left, int right)
{
assert(a);
if (left < right) {
int div = PartSort1(a, left, right);
QuickSort(a, left, div - 1);
QuickSort(a, div + 1, right);
}
}