Сортировка частично отсортированного массива

Возможный дубликат:
Интервью Q: сортировка почти отсортированного массива (элементы неуместны не более, чем k)

У меня есть частично отсортированный массив с тем свойством, что каждый элемент находится внутри d единиц его правильно отсортированной позиции. Мне интересно, есть ли способ отсортировать этот массив - используя этот факт - менее чем за n log n время.

Ответы

Ответ 1

Сверху моей головы...

Создайте "скользящее окно" размера 2d.

Запустите его на [0,2d). Сортировка элементов в окне; теперь элементы с 0 по d-1 гарантированы как правильные.

Сдвиньте окно вперед на d, так что теперь он [d, 3d). Отсортируйте эти элементы, гарантируя правильность элементов d-2d-1.

Сдвиньте вперед другой d, так что теперь его [2d, 4d]. Сортируйте их. И так далее.

Каждый вид O (d log d), и для достижения конца требуется n/d шагов, поэтому это O (n/d * d log d) = O (n log d). Если d постоянна, то O (n).

[править]

Вы хорошо отмечаете комментарий; Я не доказывал, что каждая итерация сохраняет свойство, что каждый элемент находится внутри d единиц его правильного положения.

Итак...

Лемма: если A - массив с тем свойством, что каждый элемент находится внутри d единиц его правильного положения, и вы сортируете любую непрерывную подпоследовательность внутри A для создания массива A ', то каждый элемент из A' находится внутри d единиц его надлежащего положения.

Доказательство. Так как это лемма о свойствах сортировки (не производительности), не имеет значения, какой алгоритм мы используем для сортировки. Поэтому используйте сортировку пузырьков. Найдите любые два элемента в подпоследовательности, которые вышли из строя, и замените их. Есть только три случая: оба элемента находятся перед их правильными позициями в массиве; оба находятся после их правильных позиций в массиве; или они находятся между их соответствующими позициями в массиве.

Например, предположим, что A [i] принадлежит в позиции я 'и A [j] принадлежит в позиции j', я < j, но A [i] > A [j]. Отсюда следует, что я ' > j' (потому что это то, где элементы "принадлежат", и A [i] > A [j]). Случай 1: предположим, что я 'и j' больше, чем я и j; то есть порядок переходит я < j < j ' я'. Но по условию я 'является только d единицами из i, поэтому весь этот диапазон составляет всего d единиц в ширину в лучшем случае. Таким образом, j также находится внутри d единиц я 'и я находится внутри d единиц j', поэтому, когда мы меняем A [i] на A [j], оба элемента все еще находятся в пределах d от того, где они принадлежат. Анализ для случая 2 и случая 3 аналогичен.

Таким образом, каждый шаг сортировки пузырьков - на любой подпоследовательности A - сохранит искомое свойство, из которого следует, что вся сортировка пузырьков сохранит искомое свойство, из которого следует, что любой вид сохранит желаемое свойство. Q.E.D.

Ответ 2

Да; можно сортировать в O (nd) времени. Одним из решений является простая модификация сортировки вставки. Мы обрабатываем входной массив от начала до конца; для каждого элемента мы рассмотрим последние элементы d выходного массива и вставим новый элемент в соответствующее положение.

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

Ответ 3

Угу. Верьте или нет, что сортировка пузырьков, вероятно, лучше всего для частично отсортированного массива. Лучшим случаем является полностью отсортированный массив, и в этом случае его производительность равна O (n).

Википедия по типам пузырей: http://en.wikipedia.org/wiki/Bubble_sort

Изменить: В частности, "Измененная сортировка пузырьков", с флагом, чтобы пропускать обмены, когда он уже в порядке.

Ответ 4

Я верю Timsort (который, как я думаю, использует Python?) делает именно это.