首先,对快速排序分析可知,在一个包含n个元素的数组上运行快速排序时,记总共的两个元素之间的比较次数为X,则快速排序的运行时间为
将数组A中的各个元素重新命名为
则算法的总共的比较次数为:
对上述式子两边取期望可得:
通常,假设每个元素的值是互异的,因此,一旦一个满足
接着计算这一事件发生的概率。在任意一个
所以有:
所以,可以有:
由此可得,在输入元素均不相同的情况下,随机化的快速排序算法的期望运行时间是
对于上式,又有:
所以,又有,随机化的快速排序算法的期望运行时间为
当输入数据已经几乎有序时,插入排序的速度很快。在实际应用中,可以利用这一特点来提高快速排序的速度。当对一个长度小于k的子数组调用快速排序时,可以让它不做任何处理就返回。当上层快速排序调用返回后,对整个数组进行插入排序来完成排序过程。该算法的期望时间复杂度为
对于快速排序结束后的插入排序,假设每一小结的插入排序时间复杂度为O(k^2),则n/k个小结的时间复杂度为
对于随机的快速排序过程,时间复杂度是
C语言实现优化的快速排序如下:
void insertion_sort(int *source, int head, int tail) {
if (head > tail) {
fprintf(stderr, "Error head and tail\n");
return;
}
int i = head + 1;
int j = head;
int temp;
for (i = head + 1; i <= tail; i++) {
temp = source[i];
for (j = i - 1; j >= head && source[j] > temp; j--) {
source[j + 1] = source[j];
}
source[j + 1] = temp;
}
}
int randomized_partition(int *source, int head, int tail) {
swap(source + rand() % (tail - head + 1) + head, source + tail);
int x = source[tail];
int i = head - 1, j = head;
for (j = head; j < tail; j++) {
if (source[j] <= x) {
i++;
swap(source + j, source + i);
}
}
swap(source + tail, source + i + 1);
return i + 1;
}
void limited_quick_sort(int *source, int head, int tail, int k) {
if (tail - head >= k)
return;
int mid = randomized_partition(source, head, tail);
limited_quick_sort(source, head, mid - 1, k);
limited_quick_sort(source, mid + 1, tail, k);
}
void insertion_optimized_quick_sort(int *source, int head, int tail, int k) {
limited_quick_sort(source, head, tail, k);
insertion_sort(source, head, tail);
}