Чтобы доказать, что алгоритм работает за линейное время, давайте немного его изменим (мы изменим только порядок деления и объединения блоков, не более того):
(1): Divide input into n/4 blocks, each has size 4.
(2): Until there is more than one block, repeat:
Merge each pair of adjacent blocks into one block of size 4.
(For example, if we have 4 blocks, we will split them in 2 pairs -
first pair contains first and second blocks,
second pair contains third and fourth blocks.
After merging we will have 2 blocks -
the first one contains 4 least elements from blocks 1 and 2,
the second one contains 4 least elements from blocks 3 and 4).
(3): The answer is the last element of that one block left.
Доказательство: факт, что Массив постоянной длины (в вашем случае 4) можно отсортировать за постоянное время. Пусть k = log (n). L oop (2) выполняет k-2 итерации (на каждой итерации количество оставшихся элементов делится на 2, пока не останется 4 элемента).
До i-й итерации (0 <= i < k-2) осталось (2 ^ (ki)) элементов, поэтому осталось 2 ^ (ki-2) блоков, и мы объединяем 2 ^ (ki-3) пары блоков. Давайте найдем, сколько пар мы будем объединять во всех итерациях. Количество слияний равно </p>
mergeOperationsCount = 2^(k-3) + 2^(k-4) + .... + 2^(k-(k-3)) =
= 2^(k-3) * (1 + 1/2 + 1/4 + 1/8 + .....) < 2^(k-2) = O(2^k) = O(n)
Поскольку мы можем объединить каждую пару в постоянное время (поскольку они имеют постоянный размер), и единственная операция, которую мы выполняем, - это объединение пар, алгоритм выполняется за O (n).
И после этого доказательства я хочу заметить, что существует еще один линейный алгоритм, который тривиален, но он не разделяй и властвуй.