Соседние элементы в результатах быстрой сортировки: гарантирует ли алгоритм их прямое сравнение?

Гарантируется ли алгоритмом быстрой сортировки прямое сравнение соседних элементов выходного массива?

Другими словами: В ходе сортировки алгоритм быстрой сортировки выполняет (k-2)2^k+2 сравнения в лучшем случае и 2^(2k-1)-3*2^(k-1)+1 сравнения в наихудший сценарий, когда количество сортируемых элементов (N) выражается как N=2^k-1.

Это много сравнений, но можем ли мы быть уверены, что соседние элементы, появляющиеся в отсортированном порядке в выходном массиве «a[]», сравнивались напрямую хотя бы один раз в ходе работы алгоритма? Так:

cmp(a[1], a[2]); cmp(a[2], a[3]); cmp(a[3], a[4]); ... ; cmp(a[N-1], a[N]);

@derpirscher: По вашему мнению, какой алгоритм сортировки дает такую ​​гарантию?

George Robinson 02.07.2024 12:05

Например, сортировка вставкой или пузырьковая сортировка.

derpirscher 02.07.2024 12:06

Я подозреваю, что некоторые утверждения по этому поводу будут основываться на уникальных значениях ключей или подразумевать их.

greybeard 02.07.2024 12:37

Связано с тем, что, я думаю, вы делаете: Какой алгоритм сортировки использует наименьшее количество сравнений?

Neil 02.07.2024 19:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Да! Рассмотрим дерево, образованное различными операциями над разделами, со сводным элементом раздела, связанным с этим узлом. Узлы увеличиваются при последовательном обходе. Для любого заданного немаксимального узла узел, следующий сразу за ним в отсортированном порядке, является либо предком (указывая на то, что, когда этот узел был опорным, этот узел сравнивался с ним), либо потомком (указывая обратное).

Я не уверен, как бы вы воспользовались этой гарантией, но она есть.

В более общем смысле, этим свойством обладает любой алгоритм сортировки на основе сравнения. Рассмотрим два узла, которые оказываются последовательными в отсортированном порядке. В какой-то момент они должны были непосредственно сравниваться друг с другом, потому что никакая транзитивная цепочка сравнений не могла бы иначе доказать, что левое меньше правого.

Например, предположим, что отсортированный порядок содержит кусочки...foo, bar, baz, qux.... Вполне возможно, что foo и qux никогда не сравнивались друг с другом: вместо этого каждый из них мог быть сравнен с bar или baz, или каждый из них мог быть сравнен друг с другом, а затем bar и baz сравнивались друг с другом. Но вы знаете, что foo и bar сравнивались напрямую, потому что никакой другой процесс не мог установить, что порядок должен был быть именно таким, а не ...bar, foo, baz, qux.... В конце концов, нет другого элемента, который мог бы помочь.

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

vals 02.07.2024 12:14

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

Sneftel 02.07.2024 12:16

@Sneftel: Я все еще анализирую твой ответ. Кроме того, что касается вашего вопроса: я бы использовал эту гарантию, чтобы избежать повторения одних и тех же сравнений после сортировки массива. В стандартной библиотеке языка C реализация qsort() использует определяемую пользователем функцию сравнения. Я хотел бы проделать дополнительную работу внутри этой функции и воспользоваться преимуществами уже выполненных сравнений, чтобы мне не приходилось повторять их после того, как алгоритм быстрой сортировки выполнит свою работу. В моем случае эти сравнения очень дороги, поскольку на каждое сравнение приходится в среднем 65536 байт!

George Robinson 02.07.2024 12:20

@GeorgeRobinson Звучит хорошо, но имейте в виду, что даже если у вас не было этой гарантии, вы все равно можете использовать мемоизацию, чтобы избежать повторного расчета необходимых последовательных сравнений.

Sneftel 02.07.2024 14:34

Другие вопросы по теме