Рассмотрим два k-битных числа (в двоичном представлении):
$$A = A_1 A_2 A_3 A_4 ... A_k $$
$$B = B_1 B_2 B_3 B_4 ... B_k $$
чтобы сравнить, мы сканируем слева направо в поисках появления 0
и проверяем противоположное число, если эта цифра также является 0
(для обоих чисел), замечая, что если когда-либо такой случай будет найден, то источник 0
меньше, чем источник 1
. Но что, если числа:
111111111111
111111111110
ясно, что это потребует сканирования всего числа, и если нам ничего не говорят о числах заранее, а просто дают их, то:
Сравнение занимает $O(k)$
времени.
Поэтому, когда мы смотрим на код метода сортировки, такого как высокопроизводительная быстрая сортировка:
HPQuicksort(list): T(n)
check if list is sorted: if so return list
compute median: O(n) time (or technically: O(nk))
Create empty list $L_1$, $L_2$, and $L_3$ O(1) time
Scan through list O(n)
if element is less place into $L_1$ O(k)
if element is more place into $L_2$ O(k)
if element is equal place into $L_3$ O(k)
return concatenation of HP sorted $L_1$, $L_3$, $L_2$ 2 T(n/2)
Таким образом: T(n) = O(n) + O(nk) + 2*T(n/2) ---> T(n) = O(nklog(n))
Это означает, что быстрая сортировка медленнее, чем сортировка по основанию.
Почему же мы до сих пор его используем?
O(k *n * log(n))
. Насколько это актуально? Я мог бы придумать тип данных, который требует O(n!) времени для сравнения. Я мог бы придумать другой специализированный алгоритм сортировки, который может сортировать их за время O(n). Но единственный раз, когда мой алгоритм был бы лучше, был бы при сортировке этой конкретной вещи. В 99,99999% случаев алгоритм O(n * log(n)) будет лучшим вариантом. - person GVH   schedule 14.02.2014