Структура даних купи: Що таке купа?
⚡ Розумний підсумок
Структура даних купи (Heap Data Structure) — це спеціалізоване повне бінарне дерево, де кожен батьківський вузол підтримує суворий порядок зв'язків зі своїми дочірніми вузлами, що дозволяє виконувати логарифмічні вставки, видалення та операції з пріоритетною чергою під час сортування, планування та роботи з графами.

Що таке структура даних купи?
Купа (Heap) — це спеціалізована деревоподібна структура даних. Структура даних купи складається з найвищого вузла, який називається коренем (батьківським вузлом). Його другий вузол є лівим дочірнім вузлом кореня, а третій вузол — правим дочірнім вузлом кореня. Наступні вузли заповнюються зліва направо. Ключ батьківського вузла порівнюється з ключем його нащадка, щоб досягти правильного розташування. Дерево легко візуалізувати, де кожна сутність називається вузлом, і кожен вузол має унікальний ключ для ідентифікації.
Простіше кажучи, купа (Heap) — це повне бінарне дерево, яке задовольняє властивість купи: кожен батьківський елемент упорядкований послідовно відносно своїх дочірніх елементів, що робить його ідеальним для черг за пріоритетом та сортування купою (Heap Sort).
Навіщо вам потрібна структура даних купи?
Ось основні причини використання купи:
- Структура даних Heap дозволяє видалення та вставку за логарифмічний час – O(log2п).
- Дані в дереві розташовані в певному порядку. Окрім оновлення або запиту значень, таких як максимум або мінімум, програміст може знаходити зв'язки між батьківськими елементами та елементами-нащадками.
- Ви можете застосувати концепцію Модель об'єкта документа щоб допомогти вам візуально зрозуміти структуру даних купи.
- Купи підтримують ефективні операції з чергою пріоритетів, які є критично важливими для графових алгоритмів, таких як найкоротший шлях Дейкстри та мінімальне охоплююче дерево Прима.
Типи куп
Структура даних купи має різні алгоритми для обробки вставки та видалення елементів, включаючи чергу пріоритетів, двійкову купу, біноміальну купу та Сортування купи.
- Черга пріоритетів: Це пресtracСтруктура даних t, що містить об'єкти з пріоритетом. Кожен об'єкт або елемент має заздалегідь визначений пріоритет. Таким чином, об'єкт або елемент, якому призначено вищий пріоритет, отримує послугу раніше за інших.
- Бінарна купа: Бінарні купи підходять для простих операцій з купою, таких як видалення та вставки. Вони є реалізацією за замовчуванням для більшості черг пріоритетів стандартних бібліотек.
- Біноміальна купа: Біноміальна купа складається з серії колекцій біноміальних дерев, які складають купу. Біноміальне дерево купи не є звичайним деревом, оскільки воно суворо визначене. Загальна кількість елементів у біноміальному дереві завжди дорівнює 2.n вузли.
- Сортування купи: На відміну від більшості алгоритмів сортування, сортування купою використовує простір O(1) для своєї операції сортування. Це алгоритм сортування на основі порівняння, де сортування відбувається у порядку зростання, спочатку перетворюючи вхідні дані на Max-Heap. Ви можете розглядати сортування купою як оновлене двійкове дерево пошуку.
Зазвичай, структура даних типу «купа» використовує дві стратегії. Для вхідних даних 12 – 8 – 4 – 2 та 1:
- Min-Heap – найменше значення зверху
- Макс-Хіп – найвище значення зверху
Min-Heap
У структурі Min-Heap кореневий вузол має значення, що дорівнює або менше, ніж значення дочірніх вузлів цього вузла. Таким чином, корінь Min-Heap містить мінімальне значення. Min-Heap також є повним бінарним деревом.
Як тільки у вас є мінімальна купа в дереві, всі листки є життєздатними кандидатами на максимальне значення. Однак, вам потрібно дослідити кожен листок, щоб отримати точне значення максимальної купи.
Приклад мінімальної купи
На діаграмі вище можна помітити чітку послідовність від кореня до найнижчого вузла.
Припустимо, ви зберігаєте елементи в масиві Array_N[12, 2, 8, 1, 4]. Як видно з масиву, кореневий елемент порушує пріоритет Min-Heap. Щоб зберегти властивість Min-Heap, потрібно виконати операції min-heapify для обміну елементами, доки не будуть виконані правила Min-Heap.
Макс-Хіп
У структурі Max-Heap батьківський або кореневий вузол має значення, що дорівнює або більше, ніж у його дочірніх вузлів. Цей вузол містить максимальне значення. Це повне бінарне дерево, тому ви можете побудувати Max-Heap з колекції значень за час O(n).
Ось кілька методів, які зазвичай використовуються під час впровадження Java Max-Heap:
- Додати (): Розміщує новий елемент у купі. Якщо ви використовуєте масив, об'єкти додаються в кінець масиву, тоді як у бінарному дереві об'єкти додаються зверху вниз, а потім зліва направо.
- Видалити (): Цей метод дозволяє видалити перший елемент зі списку масиву. Оскільки щойно підвищений елемент більше не є найбільшим, метод Sift-Down завжди переміщує його на нове місце.
- Просіювання (): Цей метод порівнює кореневий об'єкт з його дочірніми об'єктами, а потім переміщує переміщений вузол на його законну позицію.
- Просіювання (): Якщо ви використовуєте метод масиву для додавання щойно вставленого елемента до масиву, то метод Sift-Up допомагає щойно доданому вузлу переміститися на правильну позицію. Новий елемент спочатку порівнюється з батьківським, імітуючи структуру даних дерева.
Застосуйте формулу Parent_Index = Child_Index / 2. Продовжуйте робити це, доки максимальний елемент не опиниться на початку масиву.
Базова купа Operaвих
Щоб знайти найбільше та найменше значення в наборі даних, вам потрібно кілька основних операцій з купою, таких як пошук, вставка та видалення. Оскільки елементи постійно з'являються та зникають, вам слід знати, як:
- знайти – Шукайте предмет у купі.
- Insert – Додати нову дитину в купу.
- видаляти – Видалити вузол із купи.
Створення куп
Процес побудови куп називається створенням куп. Маючи список ключів, програміст створює порожню купу, а потім по черзі вставляє інші ключі, використовуючи основні операції з купою.
Отже, почнемо створювати мініатюрну купу (Min-Heap) за допомогою методу Вільяма, вставляючи значення 12, 2, 8, 1 та 4. Ви можете створити купу з n елементів, почавши з порожньої купи, а потім послідовно заповнюючи її іншими елементами, використовуючи час O(n log n).
- Хіпіфікація: Процедура вставки, яка допомагає вставляти елементи в купу, зберігаючи при цьому властивість купи.
Наприклад, операція max-heapify перевіряє, чи значення батьківського елемента більше, ніж значення його нащадка. Потім елементи можна сортувати за допомогою методів, таких як swapping.
- Об’єднати: Коли у вас є дві купи для об'єднання в одну, використовуйте операцію злиття, щоб об'єднати значення з двох куп. Початкові купи зберігаються.
Огляньте відвали
Перевірка куп означає перевірку кількості елементів у структурі даних купи та перевірку того, чи купа порожня.
Важливо перевіряти купи під час сортування або постановки елементів у чергу. Важливо перевірити наявність елементів для обробки за допомогою Is-Empty(). Розмір купи допоможе знайти корені Max-Heap або Min-Heap, тому вам потрібно знати, скільки елементів слідує за властивістю купи.
- Розмір – повертає величину або довжину купи. Він показує, скільки елементів зберігається в відсортованому порядку.
- Пусто – повертає TRUE, якщо купа дорівнює null, інакше повертає FALSE.
Тут ви друкуєте всі елементи в пріоритетQ циклу, а потім перевірити, що priorityQ не порожній.
//print head the head values While (!priorityQ.isEmpty()) { System.out.print(priorityQ.poll()+" ");
Використання структури даних купи
Структура даних купи корисна в багатьох програмних застосунках у реальному житті, таких як:
- Допомагає у фільтрації спаму.
- Реалізація графових алгоритмів, таких як Дейкстра та Прим.
- Operaбалансування навантаження системи та стиснення даних.
- Знаходження порядкових статистик, таких як k-й найменший елемент.
- Реалізація черг пріоритетів, де можна шукати елементи у списку за логарифмічний час.
- Структура даних купи також використовується для сортування за допомогою сортування купи.
- Моделювання клієнтів у черзі очікування.
- Обробка переривань у Operating System.
- У кодуванні Хаффмана для стиснення даних.
- Використання пошуку за принципом «спочатку найкращий» та евристики A* у плануванні шляхів за допомогою штучного інтелекту.
Властивості черги пріоритету купи
Наступні властивості описують поведінку черги пріоритетів, побудованої на купі:
- У купах пріоритетів елементи даних у списку порівнюються один з одним, щоб визначити менший або більший елемент.
- Елемент поміщається в чергу, а потім видаляється в порядку пріоритетності.
- Кожен елемент у черзі пріоритетів має унікальний номер, пов'язаний з ним, який позначено як пріоритет.
- Після виходу з черги пріоритетів, елемент з найвищим пріоритетом виходить першим.
Кроки для реалізації черги пріоритетів купи в Java
Наступна секція переходить у бетон Java реалізація, яка перетворює ці правила на робочий код.
Купа Сортувати в Java з Code Приклад
import java.util.Arrays; public class HeapSort { public static void main(String[] args) { int[] arr = {5, 9, 3, 1, 8, 6}; // Sort the array using heap sort heapSort(arr); // Print the sorted array System.out.println(Arrays.toString(arr)); } public static void heapSort(int[] arr) { // Convert the array into a heap for (int i = arr.length / 2 - 1; i >= 0; i--) { heapify(arr, arr.length, i); } // Extract the maximum element from the heap and place it at the end of the array for (int i = arr.length - 1; i >= 0; i--) { int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; heapify(arr, i, 0); } } public static void heapify(int[] arr, int n, int i) { int largest = i; int left = 2 * i + 1; int right = 2 * i + 2; // Find the largest element among the root, left child, and right child if (left < n && arr[left] > arr[largest]) { largest = left; } if (right < n && arr[right] > arr[largest]) { largest = right; } // If the largest element is not the root, swap and heapify the sub-tree if (largest != i) { int temp = arr[i]; arr[i] = arr[largest]; arr[largest] = temp; heapify(arr, n, largest); } } }
Вихід
Original Array: 5 9 3 1 8 6 Heap after insertion: 9 8 6 1 5 3 Heap after sorting: 1 3 5 6 8 9
Купа Сортувати в Python з Code Приклад
def heap_sort(arr): """ Sorts an array in ascending order using heap sort algorithm. Parameters: arr (list): The array to be sorted. Returns: list: The sorted array. """ n = len(arr) # Build a max heap from the array for i in range(n // 2 - 1, -1, -1): heapify(arr, n, i) # Extract elements from the heap one by one for i in range(n - 1, 0, -1): arr[0], arr[i] = arr[i], arr[0] # swap the root with the last element heapify(arr, i, 0) # heapify the reduced heap return arr def heapify(arr, n, i): """ Heapifies a subtree with the root at index i in the given array. Parameters: arr (list): The array containing the subtree to be heapified. n (int): The size of the subtree. i (int): The root index of the subtree. """ largest = i # initialize largest as the root left = 2 * i + 1 # left child index right = 2 * i + 2 # right child index # If left child is larger than root if left < n and arr[left] > arr[largest]: largest = left # If right child is larger than largest so far if right < n and arr[right] > arr[largest]: largest = right # If largest is not root if largest != i: arr[i], arr[largest] = ( arr[largest], arr[i], ) # swap the root with the largest element heapify(arr, n, largest) # recursively heapify the affected subtree arr = [4, 1, 3, 9, 7] sorted_arr = heap_sort(arr) print(sorted_arr)
Вихід
[1, 3, 4, 7, 9]
Далі ви дізнаєтесь про Метод розрізу навпіл.




