快速排序是排序算法中效率相对较高的,但使用的人却是比较少。大家一般信手拈来的排序算法就是冒泡排序,因为冒泡排序主观,容易理解。而快速排序使用到了递归,大家可能就有点不知所措了。(以上5毛)
算法简介
快速排序由C. A. R. Hoare在1962年提出。
基本思想:
通过一趟排序将要排序的数据列分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小;
然后再按此方法对这两部分子数据列分别1操作,直到子数据的大小为0或1。
![快速排序示例](http://i1.piimg.com/567571/78dba725091d8317.gif)
算法步骤:
- 设置left、right变量用于记录移动下标;
- 从数列中挑出一个元素,记称为 value,一般选择array[start]或array[end](此处我们选取array[start]);
- 从right开始向前搜索(right--),找到第一个小于value的值array[right],将array[right]赋给array[left] (此处array[left]已被记录,故不用担心被覆盖);
- 从left开始向后搜索(left++),找到第一个大于value的值array[left],将array[left]赋给array[right](同理:此处array [right] 已被记录,故不用担心被覆盖);
- 重复3、4步,直到 left==right;
- 递归以上步骤完成对整个数列排序。
代码实现
本例为升序排列,且用较为简单的数据来演示
#include <stdio.h>
void printArray(int *array, int length)
{
printf("array:\n");
for (int index = 0; index < length; index++)
{
printf(" %d", *(array + index));
}
printf("\n\n");
}
void quickSort(int array[], int start, int end)
{
if (start >= end) //数列size为0或1
{
//递归出口
return;
}
//因为需要对元素进行移动,需复制一份左右下标用于移动
int left = start;
int right = end;
int value = array[start]; //选取数列第一个元素为基准
while (left < right)
{
while (left < right && value <= array[right])//从后选取第一个小于基准的元素
{
right--;
}
array[left] = array[right];//换位。此处会产生自己赋值自己情况,可加判断取消
/*printf("后向前移");
printArray(array, 4);*/
while (left < right && value >= array[left])//从前选择第一个大于基准的元素
{
left++;
}
array[right] = array[left];//换位
/*printf("前向后移");
printArray(array, 4);*/
}
array[left] = value;
/*printf("一次完成");
printArray(array, 4);*/
//递归
quickSort(array, start, left - 1);
quickSort(array, left + 1, end);
}
int main()
{
int array[4] = { 2,3,1,4 };
printArray(array, 4);
quickSort(array, 0, 3);
printArray(array, 4);
return 0;
}
运行结果:
复杂度分析
关于快速排序的时间复杂度和空间复杂度,大家可以参考:排序算法之 快速排序 及其时间复杂度和空间复杂度
刚玩博客,如果有什么错误之处或建议,请在评论区告诉我,谢谢!