快速排序的精髓就在partition
函数的实现。我们构建两个指针,将数组分为三部分,黑色部分全部小于pivot
,中间蓝色部分都大于pivot
,后面红色部分未知。i
指针遍历整个数组,只要它指向的元素小于pivot
就交换两个指针指向的元素,然后递增。
// arr[]为数组,start、end分别为数组第一个元素和最后一个元素的索引
// povitIndex为数组中任意选中的数的索引
int partition(int arr[], int start, int end, int pivotIndex)
{
int pivot = arr[pivotIndex];
swap(arr[pivotIndex], arr[end]);
int storeIndex = start;
//这个循环比一般的写法简洁高效
for(int i = start; i < end; ++i) {
if(arr[i] < pivot) {
swap(arr[i], arr[storeIndex]);
++storeIndex;
}
}
swap(arr[storeIndex], arr[end]);
return storeIndex;
}
两次swap
是为了将pivot
先暂存在最后一个位置,在完成一次partition
之后将pivot
还原至storeIndex
所指的位置。因为它之前的元素都小于它,之后的都大于它。
如果没有这两次swap
,那么storeIndex
将指向大于等于pivot
的元素,并不能保证它之后的元素都大于pivot
(能保证之前的都是小于的)。storeIndex
位置的元素一旦固定直至程序结束将不会再改变,因此需要使用两次交换暂存pivot
元素。
时间: 2024-11-08 04:22:25