Что касается слияния на месте в массиве

Я столкнулся со следующим вопросом.

Дан массив из n элементов и целое число k, где kn. Элементы {a 0 ... a k} и { a k +1 ... a n} являются уже отсортировано. Приведите алгоритм сортировки за O (n) времени и O (1) пространство.

Мне не кажется, что это можно сделать за время O (n) и пространство O (1). Кажется, проблема действительно заключается в том, чтобы спросить, как выполнить этап слияния сортировки слиянием, но на месте. Если бы это было возможно, разве не было бы так реализовано слияние? Я не могу убедить себя, и мне нужно мнение.


person Sid    schedule 19.07.2010    source источник
comment
В вопросе конкретно говорится о сортировке слиянием? Я знаю, что можно объединить сортировку на месте, но не за время O (n) (по крайней мере, я никогда об этом не слышал).   -  person jrista    schedule 20.07.2010
comment
Нет. Я провожу аналогию с этапом слияния. Это действительно похоже.   -  person Sid    schedule 20.07.2010
comment
Если вы опубликовали точную формулировку вопроса, то, похоже, он не имеет никакого отношения к сортировке слиянием. Существуют алгоритмы сортировки, которые занимают пространство O (1) и O (n) на месте для предварительно отсортированного массива (то есть сортировки вставкой). Mergesort не входит в их число, и хорошо известно, что он не входит в их число, так что ...   -  person jrista    schedule 20.07.2010
comment
Итак, как бы вы тогда решили эту проблему за O (n) время? Что за идея? Возможно, вы не поняли вопрос, вот пример ... {1,3,5,8} и {2,4,6,9} .. То, что вы имеете в виду, является полностью предварительно отсортированным массивом, который не является случай на мой вопрос. В любом случае сортировать уже отсортированный массив не имеет смысла.   -  person Sid    schedule 20.07.2010


Ответы (3)


Это, похоже, указывает на то, что можно сделать в пространстве O (lg ^ 2 n). Я не вижу, как доказать невозможность слияния в постоянном пространстве, но я тоже не вижу, как это сделать.

Изменить: Погоня за ссылками, Кнут Том 3 - Упражнение 5.5.3 говорит: «Значительно более сложный алгоритм Л. Трабба-Пардо обеспечивает наилучший ответ на эту проблему: можно выполнить стабильное слияние за время O (n) и стабильное сортировка за время O (n lg n), используя только O (lg n) бит вспомогательной памяти для фиксированного числа индексных переменных.

Другие ссылки, которые я не читал. Спасибо за интересную задачу.

Дальнейшее редактирование: в этой статье утверждается, что в статье Хуанга и Лэнгстона есть алгоритм, который объединяет два списка размера m и n за время O (m + n), поэтому ответ на ваш вопрос будет положительным. К сожалению, у меня нет доступа к статье, поэтому я должен доверять информации из вторых рук. Я не уверен, как согласовать это с заявлением Кнута о том, что алгоритм Трабба-Пардо является оптимальным. Если бы от этого зависела моя жизнь, я бы пошел с Кнутом.

Теперь я вижу, что этот вопрос был задан как и ранее Stack Overflow вопрос a количество раз. У меня нет духа отмечать это как дубликат.

Хуан Б.-К. и Лэнгстон М. А. Практическое слияние на месте, Comm. ACM 31 (1988) 348-352

person deinst    schedule 20.07.2010
comment
Ты прав. Я могу читать газету, так как я университет. Кажется, что это возможно, хотя техника довольно сложная. Спасибо за указатель. - person Sid; 20.07.2010
comment
Вы можете найти эту статью на CiteSeerX. citeseerx.ist.psu.edu/viewdoc/summary?doi= 10.1.1.22.8523 - person Daniel Brückner; 20.07.2010
comment
@ Дэниел Спасибо. Мои навыки работы с Google нуждаются в улучшении. - person deinst; 20.07.2010

Для этого существует несколько алгоритмов, ни один из которых не очень легко понять. Ключевая идея состоит в том, чтобы использовать часть массивов для слияния в качестве буфера, а затем выполнить стандартное слияние, используя этот буфер для вспомогательного пространства. Если вы затем можете переместить элементы так, чтобы элементы буфера находились в нужном месте, вы в золотом цвете.

Я написал реализацию одного из этих алгоритмов на моем личном сайте, если вам интересно посмотреть на это. Он основан на статье Хуанга и Лэнгстона «Практическое слияние на месте». Вы, вероятно, захотите просмотреть этот документ, чтобы получить некоторое представление.

Я также слышал, что для этого есть хорошие адаптивные алгоритмы, которые используют некоторый буфер фиксированного размера по вашему выбору (который может быть O (1), если вы хотите), но затем элегантно масштабируются с размером буфера. Я не знаю ничего из этого в голове, но уверен, что быстрый поиск «адаптивного слияния» может что-то дать.

person templatetypedef    schedule 13.11.2010

Нет, это невозможно, хотя моя работа была бы намного проще, если бы это было :).

У вас есть фактор O (log n), которого вы не можете избежать. Вы можете выбрать время или пространство, но единственный способ избежать этого - не сортировать. С пространством O (log n) вы можете создать список продолжений, отслеживающих, где вы спрятали элементы, которые не совсем подходят. С помощью рекурсии это можно сделать так, чтобы оно поместилось в куче O (1), но это только при использовании вместо этого фреймов стека O (log n).

Вот прогресс слияния-сортировки шансов и равенств от 1 до 9. Обратите внимание, как вам требуется учет пространства журнала для отслеживания инверсий порядка, вызванных двойными ограничениями постоянного пространства и линейных свопов.

.     -
135792468
 .   -
135792468
  :  .-
125793468
   : .-
123795468
    #.:-
123495768
     :.-
123459768
      .:-
123456798
       .-
123456789

123456789

Есть некоторые деликатные граничные условия, которые немного сложнее, чем двоичный поиск, и даже в этой (возможной) форме, и, следовательно, плохая домашняя задача; но действительно хорошее умственное упражнение.

Обновить По-видимому, я ошибаюсь, и существует алгоритм, который предоставляет время O (n) и пространство O (1). Я скачал документы, чтобы просветить себя, и беру этот ответ как неверный.

person Recurse    schedule 20.07.2010
comment
Возможно для связанного списка. O (log n) происходит откуда-то еще. - person Joshua; 20.07.2010
comment
Я вижу, как это сделать с дополнительным пространством lg n. Я не понимаю, как доказать, что вы не можете добиться большего, т.е. что требуется O (lg n) дополнительного места, чтобы все оставалось линейным. - person deinst; 20.07.2010
comment
@Джошуа. Было бы нечестно сказать, что это возможно со связанным списком, потому что в списке есть O (n) дополнительных частей информации, которые упрощают работу - указатели от элемента к элементу. Если бы вы могли позволить себе O (n) дополнительного места, вы могли бы сделать то же самое с массивом. Вы выделяете новый массив результатов и просто просматриваете два исходных массива, копируя элементы по порядку. - person cape1232; 20.07.2010
comment
@deinst Мне было нелегко, но в конце концов я к своему удовлетворению доказал, что lg n - это нижняя граница. Это было много лет назад, и, к сожалению, у меня его больше нет. Однако достаточно просто доказать, что какая бы ни была нижняя граница, она выше, чем O (1), что достаточно для наших целей. - person Recurse; 20.07.2010