Почему итеративный k-образный слияние O (nk ^ 2)?

k-way merge - это алгоритм, который принимает в качестве входных k отсортированных массивов, каждый из которых n. Он выводит один отсортированный массив из всех элементов.

Он делает это, используя стандартную процедуру "merge" для алгоритма сортировки слияния, чтобы объединить массив 1 с массивом 2, а затем массив 3 в этот объединенный массив и так далее, пока все k массивы не будут объединены.

Я думал, что этот алгоритм O (kn), потому что алгоритм пересекает каждый из k массивов (каждый из длины n) один раз. Почему O (nk ^ 2)?

Ответ 1

Поскольку он не пересекает каждый из k-массивов один раз. Первый массив проходит k-1 раз, первый - как merge (array-1, array-2), второй - как merge (merge (array-1, array-2), array-3)... и так далее.

Результат k-1 сливается со средним размером n * (k + 1)/2, что дает сложность O (n * (k ^ 2-1)/2), которая равна O (nk ^ 2).

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

Ответ 2

На самом деле в худшем случае будет n сравнений для первого массива, 2n для второго, 3n для третьего и скоро до (k - 1) n.
Итак, теперь сложность становится просто

n + 2n + 3n + 4n + ... + (k - 1)n
= n(1 + 2 + 3 + 4 + ... + (k - 1))
= n((k - 1)*k) / 2
= n(k^2 - k) / 2
= O(nk ^ 2)

: -)

Ответ 3

Как насчет этого:

Шаг 1: Объединить массивы (1 и 2), массивы (3 и 4) и т.д. (массив k/2 объединяет 2n, общая рабочая kn).

Шаг 2: Объединить массив (1,2 и 3,4), массивы (5,6 и 7,8) и т.д. (K/4 объединяет 4n, общая рабочая kn).

Шаг 3: Повторить...

Будут log (k) такие "Шаги", каждый из которых работает на kn. Следовательно, общая работа выполнена = O (k.n.log(k)).

В противном случае, если бы мы просто отсортировали все элементы массива, мы все равно могли бы объединить все в O (k.n.log(k.n)).

Ответ 4

Я не согласен с другими ответами. Вам не нужно сравнивать элементы 1 по 1 каждый раз. Вы должны просто поддерживать самые последние элементы K в отсортированном наборе.  Вы удаляете наименьшее число и повторяете его следующим элементом. Это должно быть n.log(k)

Соответствующая статья . Отказ от ответственности: я принимал участие в написании этого документа

Ответ 5

k-way merge - это алгоритм, который принимает в качестве входных k отсортированных массивов, каждый из которых n. Он выводит один отсортированный массив из всех элементов.

Я думал, что этот алгоритм O (kn)

Мы можем опровергнуть это противоречие. Определите алгоритм сортировки для m элементов, который использует ваш алгоритм с k = m и n = 1. По этой гипотезе алгоритм сортировки преуспевает в O (m) времени. Противоречие, известно, что любой алгоритм сортировки имеет наихудший случай, по крайней мере, O (m log m).

Ответ 6

Общая реализация сохраняет массив индексов для каждого из k отсортированных массивов {i_1, i_2, i__k}. На каждой итерации алгоритм находит минимальный следующий элемент из всех k массивов и сохраняет его в выходном массиве. Поскольку вы выполняете итерации и сканирование k массивов на итерацию, общая сложность O (k ^ 2 * n).

Вот некоторый псевдокод:

Input: A[j] j = 1..k : k sorted arrays each of length n
Output: B : Sorted array of length kn

// Initialize array of indexes
I[j] = 0 for j = 1..k

q = 0

while (q < kn):
    p = argmin({A[j][I[j]]}) j = 1..k           // Get the array for which the next unprocessed element is minimal (ignores arrays for which I[j] > n)
    B[q] = A[p][I[p]]
    I[p] = I[p] + 1
    q = q + 1

Ответ 7

1) У вас есть k отсортированных массивов, каждый из которых n. Поэтому общее число элементов = k * n

2) Возьмите первый элемент всех k массивов и создайте последовательность. Затем найдите минимум этой последовательности. Это минимальное значение сохраняется в выходном массиве. Число сравнений, чтобы найти минимум k элементов, составляет k - 1.

3) Поэтому общее количество сравнений  = (сравнения/элемент) * количество элементов
 = (k - 1) * k * n
 = k ^ 2 * n//приблизительно

Ответ 8

  • У вас есть k массивов, каждый из которых содержит n элементов. Это означает, что сумма k * n элементов.

  • Рассмотрим его матрицу из k * n. Чтобы добавить первый элемент в объединенный/конечный массив, вам нужно сравнить главы k массивов. Это означает, что для одного элемента в конечном массиве вам нужно выполнить k сравнений.

Итак, из 1 и 2 для элементов Kn общее время занимает O (kk * n).