一、快速排序
快速排序应该时排序算法中最好的一种,看看它的命名都显得那么诚实。快速排序也是我们必须掌握的一种排序算法,因为面试的时候绝大概率是要出现的。
二、排序原理
这里假如数据array[10]进行排序
- 首先找个基准元素tmp,一般为第一个数据(tmp = array[0], left = 0, rgint = 9)
- 从最右边(right = 9)开始取出数据(array[9])与基准数据比较,比基准数据大,则不变(这里默认排序完成时从小到大的),right–(这时right=8),继续拿array[8]与基准数据比,直到array[right] 比基准数数小,这时把array[right] 的值赋给array[left]
- 从最左边(left = 0)开始取出数据(array[0])与基准数据比较,比基准数据小,则不变(这里默认排序完成时从小到大的),left++(这时left=1),继续拿array[1]与基准数据比,直到array[left] 比基准数数大,这时把array[left] 的值赋给array[right]
- 循环 2、3步骤,直到left >= right
- 这时我们把数据分为两个[0, left - 1] ,[right, 9],递归进行上面的1,2,3,4步骤。
- 直到数组不能再分。
网上找个图(还是看图):
三、代码示例
int quick_sort(int *array, int start, int end)
{
int right, left;
int tmp;
if (NULL == array)
return -1;
left = start;
right = end;
/*递归退出判断*/
if (left < right) {
tmp = array[left];
while (left < right) {
while (left < right && array[right] > tmp)
right --;
array[left] = array[right];
while (left < right && array[left] < tmp)
left ++;
array[right] = array[left];
}
array[right] = tmp;
quick_sort(array, start, left - 1);
quick_sort(array, right + 1, end);
}
return 0;
}
四、算法分析
- 当分区选取的基准元素为待排序元素中的最大或最小值时,为最坏的情况,时间复杂度和直接插入排序的一样,移动次数达到最大值max = 1+2+…+(n-1) = n*(n-1)/2 = O(n2) 此时最好时间复杂为O(n2)
- 当分区选取的基准元素为待排序元素中的"中值",为最好的情况,时间复杂度为O(nlog2n)。
- 快速排序的空间复杂度为O(log2n).
- 当待排序元素类似[6,1,3,7,3]且基准元素为6时,经过分区,形成[1,3,3,6,7],两个3的相对位置发生了改变,所是快速排序是一种不稳定排序。
五、测试
sort.c
int main(int argc, char **argv)
{
int i, length;
// int buf[5] = {
// 16, 32, 8, 12, 13
// };
int buf[] = {112, 5,1,11, 34, 10, 111,1234,44,33,23,56,77,88,43,41,2,4,19,13,3,8,6,0,9};
//int buf[10]={4,1,3,2,16,9,10,14,8,7};
length = sizeof(buf)/sizeof(int);
// heap_sort(buf-1, length);
// shell_sort(buf, length, 2);
quick_sort(buf, 0, length - 1);
for(i = 0; i < length; i++)
printf("%d\t ", buf[i]);
printf("\n");
return 0;
}
结果输出:
关注公众号"小败日记",搬砖过程遇到的问题,大家一起探讨,资源共享