Идея: реальные данные содержат в себе уже упорядоченные подмножества, надо это использовать. Алгоритм Timsort состоит из нескольких частей:

Алгоритм

n — размер входного массива.

run — подмассив во входном массиве, который обязан быть упорядоченным одним из двух способов:

<aside> 💡 Тут мы строим монотонность относительно i-го и (i+1)-го элемента. Пример: “6 -3” ⇒ далее должно быть в убывающем порядке. “6 10” ⇒ Дальше должно быть в неубывающем порядке.

</aside>

minrun — минимальный размер подмассива, описанного в предыдущем пункте.

Шаг 1. Вычисление minrun

int minRunLength(n) {
	int flag = 0; // будет равно 1, если среди сдвинутых битов есть хотя бы один ненулевой
	while (n ⩾ 64) {
     flag = flag | (n & 1u)
     n = n >> 1u
	}
	// now 'n' has only its старшие разряды
  return n + flag
}

Шаг 2. Алгоритм разбиения на подмассивы и их сортировка

На данном этапе у нас есть входной массив, его размер n и вычисленное число minrun. Обратим внимание, что если данные изначального массива достаточно близки к случайным, то размер упорядоченных подмассивов близок к minrun. Но если в изначальных данных были упорядоченные диапазоны, то упорядоченные подмассивы могут иметь размер, превышающий minrun.