Хотя количество слияний остается неизменным, структура слияния на самом деле делает сложность времени намного хуже. Предполагая, что у вас есть функция merge()
до merge two sorted linked lists в O(n + m)
времени (где n = размер первого списка, m = размер второго) и O(1)
, рассмотрите следующий анализ, в котором я предполагаю, что в каждом списке есть в среднем n
элементов.
- Первое слияние будет
O(n + n)
, так как мы слияние два n
-sized списки
- Второго слияние будет
O(2n + n)
, так как мы сливаясь один n
-sized списка с нашим теперь 2n
-sized списка
- Третье слияние будет
O(3n + n)
... и так далее.
На данный момент мы должны сложить все дополнения внутри Big-Oh, чтобы получить:
O(2n + 3n + 4n + 5n + ... + kn)
Сумма всех этих n
терминов существенно n*(k(k+1))/2
, потому что (k(k+1))/2
является суммой из первые k
номера. Принимая постоянные множители и члены младшего порядка из (k(k+1))/2
, мы можем видеть, что O((k(k+1))/2) = O(k^2)
, тем самым предоставляя алгоритм сложности O(n*k^2)
.
Я написал небольшую статью по этой проблеме и проанализировал дальше, степень различий в сложности. Вы должны проверить его here
Чтобы ответить на другой вопрос о том, как делает разделяй и властвуй подход на самом деле выход O (пк * журнал (K)), подумайте о том, как сортировка слиянием работает.
Если у нас есть $ n $ items, merge sort делает n
количество работы, столько раз, сколько требуется для суммирования n
элементов вместе, прежде чем они станут одним целым списком. Это число log(n)
(база базы 2 из n), поэтому требуется ряд шагов пропорционально nlog(n)
(опять же, осознаем, что делаем n
количество работ, потому что всегда есть n
элементов в игре, log(n)
раз).Причина сортировки слияния должна разбивать список на отдельные элементы до их слияния, потому что одна единица - это самая маленькая вещь, которую мы можем получить по определению, отсортированную, без какой-либо работы по ее сортировке.
В нашем случае каждый список уже отсортирован, поэтому мы можем рассматривать каждый из списков k
(размером ~ n) как элемент, отсортированный по определению. Нет необходимости разбивать отсортированный список вниз. Так как есть k
списков с элементами n
, всегда будет n*k
элементов в игре. К счастью, поскольку каждый список уже отсортирован, нам нужно объединить только k
«элементы», а не все элементы списка n*k
. Таким образом, та же логика преобладает, поскольку мы должны объединить k
элементов/списков вместе. Поскольку каждый список принимает O(n)
время для слияния, в отличие от O(1)
при работе с n*k
отдельных элементов, это занимает время пропорционально O(nk*log(k))
.
Ваш код на самом деле не делает слияние, потому что вы не указали свой код 'merge(). Все, что мы знаем, это то, что это 'O (n) * O (merge)' –