Коли я хочу використовувати купу?


92

Окрім очевидної відповіді черги пріоритетів, коли купа може бути корисною в моїх програмувальних пригодах?


8
Тут є безліч хороших відповідей, тому я переконаюся з тим, "коли купа просто недостатньо велика".
Дон Верве

Відповіді:


121

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

Однак решта масиву зберігається частково несортованою. Таким чином, миттєвий доступ можливий лише до найбільшого (найменшого) елемента. Вставки швидкі, тому це хороший спосіб мати справу з вхідними подіями чи даними та завжди мати доступ до найраніших / найбільших.

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

Куча - це дерево, де значення батьківського вузла більше, ніж значення будь-якого з його нащадкових вузлів.

Якщо ви думаєте про купу як про бінарне дерево, яке зберігається в лінійному порядку за глибиною, спочатку із кореневим вузлом (потім дочірніми вузлами, а потім дітьми цих вузлів); тоді діти вузла з індексом N знаходяться на рівні 2N + 1 та 2N + 2. Ця властивість забезпечує швидкий доступ за індексом. І оскільки кучами маніпулюють шляхом обміну вузлами, це дозволяє сортувати на місці.


3
Зауважте також, що це може бути зручний гарантований сорт NlogN, який не вимагає додаткових розподілів масивів
Overflown

38
Також чудово знати купу для питань співбесіди;)
vivekian2

21
@ vivekian2 Єдина причина, через яку я тут, - це те, що я збираюся взяти інтерв’ю.
byxor

чому б не використовувати клас стека з допоміжним стеком для відстеження найбільшого (або найменшого) елемента. пошук - O (1)
Рідхван Шейкл

@RidhwaanShakeel Якщо ви використовуєте стек, ваш предмет завжди буде розміщений на голові, що робити, якщо позицію предмета потрібно визначати на основі якоїсь властивості предмета, як найбільша подія (залежно від кількості людей, які брали участь у події).
SandeepGodara

49

Купи - це конструкції, призначені для швидкого доступу до мінімальної або максимальної .

Але чому ти цього хочеш? Ви можете просто перевірити кожен запис на add, щоб побачити, чи є він найменшим чи найбільшим. Таким чином у вас завжди є найменший або найбільший за постійний час O(1).

Відповідь полягає в тому, що купи дозволяють витягнути найменший або найбільший і швидко дізнатись НАЙБІЛЬШИЙ найменший чи найбільший . Тому це називається Пріоритетна Черга.

Приклад із реального світу (правда, не дуже справедливий):

Припустимо, у вас є лікарня, в якій відвідують пацієнтів залежно від їх віку. Найстарших завжди відвідують першими, незалежно від того, коли вони потрапили в чергу.

Ви не можете просто відстежити найстаріший, тому що якщо ви витягнете його, ви не знаєте наступного найстарішого. Для того, щоб вирішити цю лікарняну проблему, ви впроваджуєте максимальну купу . Ця купа за визначенням частково впорядкована. Це означає, що ви не можете сортувати пацієнтів за їх віком, але ви знаєте, що найстаріші завжди знаходяться вгорі, тому ви можете витягнути пацієнта за постійний час O(1)і повторно збалансувати купу в журнал O(log N).

Більш витончений приклад:

Припустимо, у вас є послідовність цілих чисел, і ви хочете відстежувати median. Медіана - це число, яке знаходиться посередині впорядкованого масиву.

Приклад:

[1, 2, 5, 7, 23, 27, 31]

У наведеному вище випадку, 7є медіаною, оскільки масив, що містить менші числа, [1, 2, 5]має однаковий розмір із масивом, що містить більші числа [23, 27, 31]. Зазвичай, якщо масив має непарну кількість елементів, медіаною є середнє арифметичне з 2 елементів посередині, наприклад (5 + 7)/2.

Тепер, як ви відстежуєте медіану? Маючи 2 купи , одна хвилинна купа, що містить числа, менші від поточної медіани, і максимальна купа, що містить цифри, більші за поточну медіану. Тепер, якщо ці купи завжди збалансовані, 2 купи будуть містити однакову кількість елементів або один матиме на 1 елемент більше, ніж інший, найбільше.

Коли ви додаєте новий елемент до послідовності, якщо число менше поточної медіани, ви додаєте його до міні-купи, інакше додаєте його до максимальної купи. Тепер, якщо купи незбалансовані (одна купа має більше, ніж на 1 елемент, ніж інша), ви витягуєте елемент із найбільшої купи і додаєте до найменшої. Тепер вони збалансовані.


6
Більш витончений приклад - дивовижний! Я обов’язково колись спробую це. Однак я думаю, що у вашому прикладі є невелика помилка. Оскільки нам потрібно отримати медіану, усереднюючи два елементи посередині. Я б припустив, що нам потрібно використовувати мінімальну купу для зберігання чисел, більших за поточну медіану, і максимальну купу для зберігання чисел, менших від поточної медіани. Таким чином ми можемо витягти два елементи посередині за постійний час і обчислити медіану? Я прав?
Кальвін Ку

12

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

Ще одна корисна характеристика купи полягає в тому, що її можна створити на місці з масиву!


3

Також добре для алгоритмів вибору (знаходження мінімальної або максимальної)


3

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


0

Ви можете використовувати minHeap або maxHeap, коли хочете отримати доступ до найменшого та найбільшого елементів відповідно.

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