一、选择合适的排序算法
对于小规模数据可以选择时间复杂度为
O
(
n
2
)
O(n^2)
O(n2)的算法,大规模的数据一般选择
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)的算法。其中归并排序不是原地排序,空间复杂度为
O
(
n
)
O(n)
O(n),数据规模大时占用内存空间大。C语言使用快速排序来实现排序函数。
应对堆栈溢出的方法,一个是设置最深的层数,超过即报错;另一个是通过在堆上模拟实现一个函数调用栈,手动模拟递归压栈、出栈的过程。
二、优化快速排序
如果数据本来是接近有序的,每次分区点pivot都是最后一个数据,导致时间复杂度退化为 O ( n 2 ) O(n^2) O(n2),这个原因是我们的分区点选择不够合理。
1. 三数取中法
每隔一个固定的长度取数据,比较后将中间值作为分区点pivot。当数组较大时,可能是“五数取中”等等。
2. 随机法
每次随机取一个元素作为分区点。
三、qsort()排序函数举例分析
对于小数据量的排序,使用归并排序,数据量大时改为快速排序。快速排序时选择分区点pivot的用的是“三数取中法”。
在快速排序的递归过程中,当区间内元素的个数小于等于4时,采用插入排序。因为在数据个数小时,无法避免时间复杂度中的低阶、系数和常数,例如快速排序的
O
(
k
n
l
o
g
n
+
c
)
O(knlogn+c)
O(knlogn+c)。
knlogn+c = 1000 * 100 * log100 + 200 //远大于10000
n^2 = 100*100 = 10000
当k和c比较大时, O ( n 2 ) O(n^2) O(n2)的算法用时更短。