Чому двійковий пошук, який потребує відсортованих даних, вважається кращим, ніж лінійний пошук?


20

Я завжди чув, що лінійний пошук - це наївний підхід, а двійковий пошук кращий за його ефективність через кращу асимптотичну складність. Але я ніколи не розумів, чому це краще, ніж лінійний пошук, коли потрібне сортування перед двійковим пошуком?

Лінійний пошук є, O(n)а двійковий пошук є O(log n). Це, мабуть, є основою того, що бінарний пошук є кращим. Але двійковий пошук вимагає сортування, яке O(n log n)відповідає найкращим алгоритмам. Тому двійковий пошук насправді не повинен бути швидшим, оскільки він потребує сортування.

Я читаю CLRS, в якому автор має на увазі, що у сортуванні вставки замість використання наївного лінійного підходу пошуку краще використовувати двійковий пошук для пошуку місця, куди потрібно вставити елемент. У цьому випадку це здається виправданим, оскільки при кожній ітерації циклу існує відсортований список, над яким можна застосувати двійковий пошук. Але в загальному випадку, коли немає гарантії щодо набору даних, в якому нам потрібно здійснювати пошук, не використовується двійковий пошук насправді гірше, ніж лінійний пошук через вимоги до сортування?

Чи є якісь практичні міркування, які я оглядаю, які роблять бінарний пошук кращим, ніж лінійний пошук? Або двійковий пошук вважається кращим, ніж лінійний пошук, не враховуючи час обчислення, необхідний для сортування?


6
Як і у багатьох інших речах, все зводиться до: "Це залежить ...;)"
Jeff B

Якщо список уже відсортований, ви думаєте, що лінійний пошук все-таки краще? Можливо, тут варто щось врахувати.
JB King

3
Кожен, хто думає про зміну заголовка , будь ласка, не приймайте частину про відсортовані дані, оскільки видалення цього робить це зовсім іншим питанням.
Асеем Бансал

Відповіді:


53

Чи є якісь практичні міркування, на які я не помічаю, що робить бінарний пошук кращим, ніж лінійний пошук?

Так - вам слід виконати сортування O (n log n) лише один раз, і тоді ви можете виконувати двійковий пошук O (log n) так часто, як вам потрібно, тоді як лінійний пошук - O (n) кожного разу.

Звичайно, це лише перевага, якщо ви фактично здійснюєте кілька запитів на одних і тих же даних. Але сценарії "пишіть один раз, читайте часто" є досить поширеними.


Якщо ви робите щось лише один раз, не дуже важливо його оптимізувати.

14

Основне припущення полягає в тому, що ви не здійснюєте один пошук.

Тож якщо вам потрібно шукати одні й ті самі дані кілька разів, вам доведеться сортувати лише один раз і ви можете отримати прибуток від двійкового пошуку.

Якщо ви шукаєте часто та маєте зміни даних, варто скористатися відсортованим списком, де нові записи відсортовані до списку.

Тому в основному двійковий пошук кращий, коли ви шукаєте один і той самий список кілька разів без необхідності вдаватися.

Коли вам потрібно кожного разу сортувати перед пошуком, немає переваги.

Зауважте, що існують алгоритми сортування, які дуже швидкі, коли список вже відсортований (або майже відсортований). Більшість визначень ефективності очікує несортованого списку.


2
Якщо ви часто шукаєте і часто вставляєте, ви можете переглянути складніші структури даних (наприклад, двійкові дерева).
MarkJ

@MarkJ основне питання оригінального плаката стосувалось пошуку в списку. Інакше я повністю з вами згоден.
Uwe Plonus

7

тому що після того, як у вас буде відсортований список, вам не потрібно буде його повторно сортувати, це означає, що якщо у вас буде більше, ніж O (log n), пошук за сортуванням заздалегідь принесе вам виграш ( O(n log n + k log n)vsO(k*n)


5

Уявіть дві телефонні книги.

Одна телефонна книга має назви в алфавітному порядку. Щоб знайти потрібний запис, ви відкриваєтеся посередині, перевіряєте запис, а потім рухаєтеся вперед або назад залежно від того, переоценили ви або підкреслили.

Інша телефонна книга має назви у випадковому порядку. Щоб знайти потрібний запис, ви починаєте на початку і продовжуєте, поки не знайдете те, що хочете.

Чи працюватиме друга книга в будь-якому місті досить розумного розміру?


3

Я думаю, що значення бінарного пошуку над лінійним пошуком є ​​контекстним. Якщо ви почнете з величезного невпорядкованого набору даних і плануєте лише вирвати з нього невелику кількість елементів, то сортування та здійснення двійкового пошуку буде проходити повільно. Якщо ви підтримуєте упорядкований список протягом усього періоду роботи програми та регулярно отримуєте доступ до нього, то двійковий пошук - це набагато кращий шлях.


3

Як і багато інших відповіли, бінарний пошук дійсно є кращим, оскільки крок сортування може бути виконаний лише один раз, а фактичний пошук може бути виконаний стільки разів, скільки вам потрібно. Однак для певних значень n (тобто певних розмірів введення) двійковий пошук завжди є більш ефективним, ніж лінійний пошук (навіть для одного прогону).

"Точка перекидання" обчислюється шляхом розв'язання асимптотичного рівняння складності:

n log n + log n = n

Як ви можете бачити на Wolfram Alpha, існує числове значення для n, яке забезпечує те, що двійковий пошук і сортування завжди швидший, ніж лише лінійний пошук. Звичайно, фактичне значення n, яке працює у вашому випадку, залежить від багатьох факторів, які можуть бути важко оцінити.

Згідно з цією цікавою статтею Марка Пробста, яка включає деякі приємні глибинні вимірювання продуктивності на поточних процесорах:

Якщо вам потрібно здійснити пошук через відсортований масив цілих чисел, а продуктивність дійсно дуже важлива, використовуйте лінійний пошук, якщо ваш масив розміром нижче 64 елементів, двійковий пошук, якщо він знаходиться вище.


2

Словами мирянина:

Якщо у вас є не упорядкований список з десятьма мільярдами предметів, а предмет, який вам трапляється шукати, є останнім, ви прочитаєте десять мільярдів елементів.

У разі двійкового пошуку індексацію можна здійснити лише один раз. Пізніші вставки можна зробити в потрібному місці для підтримання порядку.


2

Хоча вже перераховано багато вагомих причин "кращий бінарний пошук", ми можемо також ознайомитись з перевагами з точки зору користувача:

Хоча ви можете нормально жити з невеликим часом очікування, розділеним між діями введення даних, коли ви робите відсортовану вставку, ви хочете, щоб "пошук" пройшов якомога швидше. З точки зору користувача, впорядкована вставка у поєднанні з двійковим пошуком дає найкращий можливий досвід користувача.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.