Таким чином, ви хочете знати, чи існує якийсь алгоритм сортування, який не погіршиться від його середнього випадку, якщо дано функцію порівняння, подібну до:
int Compare(object a, object b) { return Random.Next(-1,1); }
... де Random.Next () - це якийсь метод, який створюватиме випадкове генерування цілого числа між вказаною включно нижньою та верхньою межею.
Відповідь насправді полягає в тому, що більшість алгоритмів сортування виконуватимуться відповідно до їх середнього випадку, оскільки вони підкоряються хоча б одній з наступних двох умов:
- Порівняння між двома унікальними елементами ніколи не робиться двічі у сортуванні та / або
- У кожній ітерації сорту визначається правильне положення принаймні одного елемента, і таким чином елемент ніколи не порівнюється.
Наприклад, SelectionSort повторює через підпис списків несортованих елементів, знаходить «найменший» та / або «найбільший» елемент (порівнюючи кожен із найбільших дотепер), розміщує його у правильному положенні та повторює. Як результат, навіть із недетермінованим компаратором, наприкінці кожної ітерації алгоритм знайде значення, яке, на його думку, є найменшим або найбільшим, замінює його елементом у позиції, яку він намагається визначити, і ніколи не враховує цей елемент знову, тому він підпорядковується умові 2. Однак під час цього процесу A і B можна порівняти кілька разів (як найбільш крайній приклад, розглянемо кілька проходів SelectionSort на масиві, відсортованому у зворотному порядку), тому він порушує Умова 1 .
MergeSort підкоряється умові 1, але не 2; у міру злиття підмасивів елементи в одному підмасиві (зліва чи справа) не порівнюються один з одним, оскільки вже визначено, що елементи на тій стороні масиву є в порядку між собою; алгоритм порівнює лише найменш занурений елемент кожного підмасиву з іншим, щоб визначити, який є меншим і повинен перейти далі у списку, що об'єднався. Це означає, що будь-які два унікальні об’єкти A і B будуть порівнюватися один з одним максимум один раз, але "остаточний" індекс елемента в повній колекції не відомий до завершення алгоритму.
InsertionSort підкоряється лише умові 1, навіть незважаючи на те, що його загальна стратегія та складність нагадують SelectionSort. Кожен несортований елемент порівнюється з відсортованими елементами, найбільшими-першими, поки не буде знайдено той, який менше, ніж досліджуваний елемент. елемент вставляється в цій точці, а потім розглядається наступний елемент. Результатом є те, що відносний порядок будь-яких A і B визначається одним порівнянням, і подальше порівняння між A і B ніколи не проводиться, але остаточне положення будь-якого елемента не може бути відоме, поки всі елементи не будуть розглянуті.
QuickSort підкоряється обомУмови. На кожному рівні шарнір вибирається і розташовується таким чином, що "ліва" сторона містить елементи менше, ніж шарнір, а "права" сторона містить елементи, що перевищують шарнір. Результатом цього рівня є QuickSort (зліва) + шарнір + QuickSort (праворуч), що в основному означає, що положення шарнірного елемента відоме (один індекс більший за довжину лівої сторони), шарнір ніколи не порівнюється з будь-яким іншим елементом після того, як він був обраний як шарнірний (він, можливо, був порівняний з попередніми шарнірними елементами, але ці елементи також відомі і не включаються в жодні підриви), і будь-які A і B, які закінчуються на протилежних сторонах повороту, ніколи не будуть порівнювали. У більшості реалізацій чистого QuickSort базовий випадок є одним з елементів, і в цей момент його поточний індекс є його кінцевим індексом, і подальше порівняння не проводиться.
( 2 / 3 )N- 1). Зі збільшенням максимального абсолютного значення результату компаратора ймовірність будь-якого порівняння повернути негатив або нуль зменшується до .5, що робить шанс закінчити алгоритм набагато менш імовірним (шанс 99 монет перевернути всі посадочні голови , що в основному доводиться до 1 до 1,2 * 10 30 )
РЕДАКТУВАННЯ ДОВГОГО ЧАСУ: Є декілька "різновидів", розроблених спеціально як приклади того, що не потрібно робити, які містять випадковий компаратор; мабуть, найвідоміший - BogoSort. Msgstr "Якщо список наданий, якщо список не в порядку, перетасуйте його та перевірте ще раз". Теоретично він врешті-решт потрапить на правильну перестановку значень, як і "неоптимізований BubbleSort" вище, але середній випадок є фактичним часом (N! / 2), і через проблему з днем народження (після достатньої кількості випадкових перестановок ви більше шансів зустріти дублюючі перестановки, ніж унікальні), існує ненульова можливість алгоритму, який ніколи не завершується офіційно, алгоритм не обмежений часом.