Это для сбалансированных слияний в общем / случайном случае (если данные данные не случайные, но имеют длинные естественные пробеги, тогда minrun
и, следовательно, выбор для них может не иметь большого значения, и баланс больше зависит от длины прогонов, чем на количество прогонов).
В общем / случайном случае вы ожидаете произвести прогоны с точно minrun
элементами. Затем, когда количество прогонов равно степени 2, вы получаете идеально сбалансированные слияния. Если количество прогонов немного больше , чем степень 2, вы получите очень несбалансированное слияние. Если количество прогонов немного меньше , чем степень 2, вы получаете лишь небольшой дисбаланс.
Опять же, это (по крайней мере, в основном) для общего / случайного случая. Например, если у вас есть девять естественных прогонов длиной 800, 100, 100, 100, 100, 100, 100, 100, 100, 100 элементов, то вы также получите идеально сбалансированные слияния, несмотря на то, что немного больше чем степень 2.
Выдержка из собственного описания Тима в listsort.txt
относительно этого выбора minrun
:
Because sortperf.py only tries powers of 2, it took a long time to notice
that 32 isn't a good choice for the general case! Consider N=2112:
>>> divmod(2112, 32)
(66, 0)
>>>
If the data is randomly ordered, we're very likely to end up with 66 runs
each of length 32. The first 64 of these trigger a sequence of perfectly
balanced merges (see next section), leaving runs of lengths 2048 and 64 to
merge at the end. The adaptive gimmicks can do that with fewer than 2048+64
compares, but it's still more compares than necessary, and-- mergesort's
bugaboo relative to samplesort --a lot more data movement (O(N) copies just
to get 64 elements into place).
If we take minrun=33 in this case, then we're very likely to end up with 64
runs each of length 33, and then all merges are perfectly balanced. Better!