Доказать алгоритм, который использует min-heap для объединения k отсортированных списков

Я читаю CLRS и имею некоторые проблемы с упражнением 6.5-8.

Дайте алгоритм O (n lg k) -time для объединения k отсортированных списков в один отсортированный список, где n - общее количество элементов во всех входах списки. (Подсказка: используйте min0heap для слияния k-way.)

Решение, как говорят все,

1) постройте мини-кучу k-элементов, используя первый элемент из k-списков,

2) extract-min(), чтобы получить наименьший элемент из кучи и добавить его в список результатов,

3) выберите следующий элемент из того же списка, что и тот, который мы только что извлекли из кучи. Вставьте его в кучу и перейдите 2).

Я могу понять, что время O (n lg k), но я не получаю правильности выбора на шаге 3). Кажется очевидным, но есть ли какие-то формальные доказательства?

Ответ 1

Основная цель доказательства правильности заключается в том, что наименьший оставшийся элемент всегда является тем, который нужно извлечь. Ключевым инвариантом в поддержке этого утверждения является то, что очередь приоритетов содержит для каждого списка наименьший элемент, оставшийся из этого списка. Из этого инварианта следует, что, поскольку наименьший оставшийся элемент также является наименьшим элементом, оставшимся из его списка, он возвращается extract-min.

Нам нужно выбрать элемент из того же списка в части 3, чтобы сохранить инвариант, чтобы каждый список имел наименьший элемент в очереди. В противном случае мы могли бы иметь такую ​​ситуацию, как

1 2
3 4

где, если мы вытаскиваем 1 из начальной очереди, содержащей 1 и 3, и заменяем ее на 4, следующая добыча будет 3, что неверно.