Использование mergesort merge() для сортировки k упорядоченных массивов

Итак, есть классическая проблема «слияния k отсортированных массивов в один длинный отсортированный массив с использованием функции merge() из сортировки слиянием». В Интернете есть много статей и видеороликов об этом, и все они приводят к тому, что «продолжайте объединять массивы 2 на 2, пока у вас не будет только один. Это занимает O (nk log k) времени». Я понимаю это объяснение этого алгоритма и этой временной сложности.

Но что, если отсортированные массивы имеют размеры

1 , 2 , 4 , 8 , 16 , . . . , 2 к
? и мы считаем н теперь это окончательная длина массива, т.е.
н "=" 1 + 2 + 4 + . . . + 2 к "=" 2 к + 1 1
Можно ли было бы объединить их все в один массив в более подходящее время?

Кроме того, не могли бы вы оценить мой псевдокод для этого алгоритма:

(Рассмотрите A как объединение всех этих массивов и индексирование, начинающееся с 1, и merge() как слияние сортировки слиянием (массив, первый индекс первого объединяемого массива, последний индекс первого объединяемого массива, последний индекс последнего объединяемого массива )):

for(m = 1; m <= lg(n+1)/2; m++){
  for(i = 1; i < k/2; i = 4*i){
    merge(A, i, i*2^(m) -1, i*4^(m) -1);
  }
}

(Я знаю, что это выглядит запутанно, поэтому я тоже спрашиваю здесь. Извините, если мой вопрос слишком расплывчатый, но любая помощь будет приветствоваться!)

(Мне также известны реализации минимальных куч, но мне нужно знать об этом методе с использованием функции merge() сортировки слиянием!)

(Спасибо, что дочитали до сюда!)

Ответы (1)

Вы должны использовать что-то вроде подхода к кодированию Хаффмана , где листья — это размеры массивов. Объедините массивы из листьев в корень, и вы получите как минимум локальный оптимум. У меня пока нет доказательств того, что это самое оптимальное решение.