Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

506 Глава 11. Сортировка, наборы и выбор

Слияние двух сортированных списков

В Кодовом Фрагменте 11.2, мы даем основанную на списке версию слияния алгоритма для merg-

луг две сортированных последовательности, S1 и S2, осуществленный как связанные списки. Главная идея состоит в том, чтобы многократно удалить самый маленький элемент из фронта одного из двух списков и добавить его до конца последовательности продукции, S, пока один из двух входных списков не пуст, в котором пункте мы копируем остаток от другого списка к S. Мы показываем выполнение в качестве примера этой версии слияния алгоритма в рисунке 11.6.

Слияние алгоритма (S1, S2, S):

Вход: Сортированные последовательности S1 и S2 и пустая последовательность S, осуществленный как

связанные списки Продукция: Сортированная последовательность S содержащий элементы от S1 и S2, в то время как S1 не пуст и S2, не пуста, делают

если S1.front () .element ()£ S2.front () .element () тогда

перемещают первый элемент S1 в конце S

S.insertBack (S1.eraseFront ())

еще

перемещают первый элемент S2 в конце S

S.insertBack (S2.eraseFront ())

перемещают остающиеся элементы S1 к S

в то время как S1 не пуст, делают

S.insertBack (S1.eraseFront ())

перемещают остающиеся элементы S2 к S

в то время как S2 не пуст, делают

S.insertBack (S2.eraseFront ()) Кодовый Фрагмент 11.2: слияние Алгоритма для слияния двух сортированных последовательностей imple-чеканивший как связанные списки.

Продолжительность для слияния

Мы анализируем продолжительность алгоритма слияния, делая некоторую простую Обь -

servations. Позвольте n1 и n2 быть рядом элементов S1 и S2, соответственно. Слияние алгоритма имеет три в то время как петли. Независимый от того, анализируем ли мы основанную на множестве версию или основанную на списке версию, операции, выполненные в каждой петле, берут O (1) время каждый. Ключевое наблюдение состоит в том, что во время каждого повторения одной из петель, один элемент скопирован или перемещен или от S1 или от S2 в S (и тот элемент больше не рассматривают). Так как никакие вставки не выполнены в S1 или S2, это наблюдение подразумевает, что общее количество повторений этих трех петель - n1 + n2. Таким образом продолжительность слияния алгоритма - O (n1 + n2).

11.1. Вид слияния 507

(a) (b) (c)

(d) (e) (f)

(g) (h)

(i)

Рисунок 11.6: выполнение слияния алгоритма, показанного в Кодовом Фрагменте 11.2.

508 Глава 11. Сортировка, наборы и выбор

11.1.3 Продолжительность вида слияния

Теперь, когда мы дали детали алгоритма вида слияния и в его множестве - базируемые и в основанные на списке версии, и мы проанализировали продолжительность решающего алгоритма слияния, используемого в побеждать шаге, давайте проанализируем продолжительность всего алгоритма вида слияния, предполагая, что этому дают входную последовательность n элементов. Для простоты мы ограничиваем наше внимание к случаю, где n - власть 2. Мы оставляем его как осуществление (Упражнение R-11.7), чтобы показать, что результат нашего анализа также держится, когда n не власть 2.

Когда мы сделали в анализе алгоритма слияния, мы предполагаем, что входная последовательность S и вспомогательные последовательности S1 и S2, созданный каждым рекурсивным вызовом вида слияния, осуществлены или множествами или связали списки (то же самое как S), так, чтобы слияние двух сортированных последовательностей могло быть сделано в линейное время.

Как мы упомянули ранее, мы анализируем алгоритм вида слияния, отсылая к дереву вида слияния T. (Отзыв фигурирует 11.2 до 11,4.) Мы называем время проведенным в узле v T продолжительность рекурсивного вызова связанный с v, исключая время взятый, ожидая рекурсивных вызовов, связанных с детьми v, чтобы закончиться. Другими словами, время, проведенное в узле v, включает продолжительность дележа, и завоюйте шаги, но исключает продолжительность повториться шага. Мы уже заметили, что детали шага дележа прямые; этот шаг бежит вовремя пропорциональный размеру последовательности для v. Кроме того, как обсуждено выше, побеждать шаг, который состоит из слияния двух сортированных подпоследовательностей, также занимает время, независимый от того, имеем ли мы дело со множествами или связанными списками. Таким образом, разрешение мне обозначить глубину узла v, время, проведенное в узле v, является O (n/2i), так как размер последовательности, обработанной рекурсивным вызовом, связанным с v, равен n/2i.

Смотря на дерево T более глобально, как показано в рисунке 11.7, мы видим, что, учитывая наше определение «времени, проведенного в узле», продолжительность вида слияния равна сумме времен, проведенных в узлах T. Заметьте, что T имеет точно 2i узлы на глубине i. У этого простого наблюдения есть важное последствие, поскольку оно подразумевает это

полное время потратило во всех узлах T на глубине, я - O (2i n/2i), который является O (n).

Суждением 11.1, высота T -⌈log n ⌉. Таким образом со времени, проведенного в каждом из⌈log n ⌉ +, 1 уровень T - O (n), у нас есть следующий результат.

Суждение 11.2: вид слияния Алгоритма сортирует последовательность S размера n в O (n, регистрируют n), время, предполагая, что два элемента S могут быть сравнены в O (1) время.

Другими словами, алгоритм вида слияния асимптотически соответствует быстрому пробегу -

время ning алгоритма вида кучи.