一 算法描述
假设有n个元素,现在要把这些元素按照从小到大的顺序进行排序,那么算法步骤如下,
- 选择中间位置的元素作为基准值(pivot value),其索引为( 0 + (n-1) ) / 2
- 从第0个元素开始从左往右找到比基准值大的元素,其索引为 i
- 从第n-1个元素开始从右往左找到比基准值小的元素,其索引为 j
- 交换这两个元素
- 从索引 i 开始,继续从左往右找到比基准值大的元素
- 从索引 j 开始,继续从右往左找到比基准值小的元素
- 交换这2个元素
- 继续查找交换,直到 i > j,即发生了相遇
- 根据 i、j 这2个索引,把元素分成两部分,即[0, j]和[i, n-1],然后在这两个部分里继续进行步骤1~8的操作
ps:基准值不一定要选择中间位置的元素,可以选择任意位置的元素
二 C代码
void quickSort(int arr[], int left, int right)
{
int i = left, j = right; // 对i和j进行初始化
int pivot = arr[(left+right)/2]; // 基准值选择中间位置的元素
int temp = 0;
while (i <= j) // 跳出while循环说明i>j,而且i-j等于1
{
while (arr[i] < pivot && i <= right) // 从左到右,找到比pivot大的元素
++i;
while (arr[j] > pivot && j >= left) // 从右到左,找到比pivot小的元素
--j;
if (i <= j) //进行交换操作
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
/* 一定要有这2步对i和j的更新,不然当i=j时while循环会无限执行下去 */
++i;
--j;
/******************************************************/
}
}
//对[left, j]做快速排序
if (left < j)
quickSort(arr, left, j);
//对[i, right]做快速排序
if (right > i)
quickSort(arr, i, right);
}
注释:
- while循环结束后,i 大于 j,且 j-i 等于1,这样就把所有的元素分割成独立的2块,即[left, j]和[j, right],然后就可以进行递归操作继续排序
- 假设有10个元素,那么该函数调用方式为quickSort(arr, 0, 9)
三 总结
快速排序使用了分而治之的思想,设计比较巧妙。理解的关键就是弄清从左到右和从右到左两个方向的查找和交换,以及这2个方向的相遇点。
如果有写的不对的地方,希望能留言指正,谢谢阅读。