关于传统快速排序的优化
因为快排对于一些特殊的情况(例如序列原本就有序、有大量重复元素等等)会进行很多完全不必要的操作,耗费大量时间。为此,我们基于上述普通快速排序算法一步步进行优化。主要是改变了传统快排的取一组数中的第一个数为基准点的方法,而是取中间的数作为基准点。如果永远取第一个元素作为枢轴的话,在数组已经有序的情况下每次划分都将得到最坏的结果,时间复杂度退化为O(n^2)。因为其中一个子序列每次都只比原序列少一个元素,该侧的递归深度将达到最大。
下面展示:
#include <stdio.h>
void quick_sort(int array[], int left, int right);
void quick_sort(int array[], int left, int right)
{
int i = left, j = right;
int temp;
int pivot;
// 基准点设置为中间元素,你也可以选择其它元素作为基准点
pivot = array[(left + right) / 2];
while (i <= j)
{
// 找到左边大于等于基准点的元素
while (array[i] < pivot)
{
i++;
}
// 找到右边小于等于基准点的元素
while (array[j] > pivot)
{
j--;
}
// 如果左边下标小于右边,则互换元素
if (i <= j)
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}
if (left < j)
{
quick_sort(array, left, j);
}
if (i < right)
{
quick_sort(array, i, right);
}
}
int main(void)
{
int array[] = {73, 108, 111, 118, 101, 70, 105, 115, 104, 67, 46, 99, 111, 109};
int i, length;
length = sizeof(array) / sizeof(array[0]);
quick_sort(array, 0, length-1);
printf("排序后的结果是:");
for (i = 0; i < length; i++)
{
printf("%d ", array[i]);
}
putchar('\n');
return 0;
}