注:这里所有的取值范围都是左闭右开
基本思想:
任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后左右子序列重复该过程,直到所有元素都排在相应位置上为止。
大概基本的框架就是:
将区间按照基准值划分为左右两半部分的常见方式有:
- hoare版本
- 挖坑法
- 前后指针
先来看看hoare版本:
- 它的做法是先找一个基准值,一般都是找最后一个元素,然后定义两个指针,一个指向开头(begin),一个指向最后(end)
- ,从开始(begin)找比基准值大的元素,直到找到停下来
- 然后用后边的那个指针(end)从后向前找比基准值小的元素,直到找到停止
- 然后把两个指针指向的元素交换,再让begin++,end–
- 继续进行上边的(3)(4)(5)操作,直到begin = end
具体代码实现:
int partion1(int*array, int left, int right)
{
//找基准值
int key = array[right - 1];
int begin = 0;
int end = right;
while (begin < end)
{
//从左向右找比基准值大的数
while (begin < end && array[begin] < key)
begin++;
//从右向左找比基准值小的数
while (begin < end && array[end - 1] >= key)
end--;
if (begin < end)
Swap(&array[begin], &array[end - 1]);
}
if (begin != right - 1)
Swap(&array[begin], &array[right - 1]);
return begin;
}
挖坑法
- 先找到基准值,定义两个指针begin(0)和end(end=right-1),end的位置是一个坑
- begin开始向后走,找比基准值大的元素,找到了就把array[begin]赋给array[end](填坑),这时begin指向的位置就变成了一个坑,end–
- 从end位置开始向前找比基准值小的元素,如果找到了,就把array[end]赋给array[begin](填坑),这时end就变成了一个坑,begin++
- 重复(2)(3)步骤,