Илюстрация на структури от данни за купчина
Има два вида купчини: max-heap и min-heap. Структурата на max-heap е мястото, където максималната стойност е коренът и стойностите стават по-малки, когато дървото се спуска надолу; всеки родител е равен или по-голям по стойност от някое от непосредствените му деца. Структура с минимална купчина е мястото, където минималната стойност е коренът и стойностите стават по-големи, когато дървото се спуска надолу; всеки родител е равен или по-малък по стойност от някое от непосредствените му деца. В следващите диаграми първата е max-heap, а втората е min-heap:
За двете купища обърнете внимание, че за двойка деца няма значение дали това отляво е по-голямата стойност. Ред на ниво в дървото, не трябва задължително да се попълва от минимум до максимум, отляво; не е задължително да се попълва и от максимум до минимум, отляво.
Представяне на купчина в масив
За да може софтуерът лесно да използва купчината, тя трябва да бъде представена в масив. Максималната купчина по-горе, представена в масив, е:
89, 85, 87, 84, 82, 79, 73, 80, 81,,, 65, 69Това се прави, като се започне с основната стойност като първата стойност за масива. Стойностите се поставят непрекъснато чрез четене на дървото отляво надясно, отгоре надолу. Ако елемент отсъства, неговата позиция в масива се пропуска. Всеки възел има две деца. Ако възел е с индекс (позиция) n, първото му дете в масива е с индекс 2n + 1, а следващото му дете е с индекс 2n + 2. 89 е с индекс 0; първото му дете, 85 е с индекс 2 (0) + 1 = 1, докато второто му дете е с индекс 2 (0) + 2 = 2. 85 е при индекс 1; първото му дете, 84, е с индекс 2 (1) + 1 = 3, докато второто му дете, 82 е с индекс 2 (1) + 2 = 4. 79 е при индекс 5; първото му дете, 65 е с индекс 2 (5) + 1 = 11, докато второто му дете е с индекс 2 (5) + 2 = 12. Формулите се прилагат към останалите елементи в масива.
Такъв масив, където значението на елемент и връзката между елементите се подразбира от позицията на елемента, се нарича имплицитна структура на данните.
Имплицитната структура на данните за горния min-heap е:
65, 68, 70, 73, 71, 83, 84,,, 79, 80,,, 85, 89Горното max-heap е пълно двоично дърво, но не и пълно двоично дърво. Ето защо някои места (позиции) са празни в масива. За пълно двоично дърво никое местоположение няма да бъде празно в масива.
Сега, ако купчината беше почти пълно дърво, например, ако липсваше стойност 82, тогава масивът щеше да бъде:
89, 85, 87, 84,, 79, 73, 80, 81,,, 65, 69В тази ситуация три места са празни. Формулите обаче все още са приложими.
Операции
Структурата на данните е формат на данните (напр.ж. дърво), плюс връзката между стойностите, плюс операциите (функциите), изпълнявани върху стойностите. За купчината връзката, която преминава през цялата купчина, е, че родителят трябва да е равен или по-голям по стойност от децата, за макс купчина; а родителят трябва да е равен или по-малък по стойност от децата за минимална купчина. Тази връзка се нарича свойство купчина. Операциите на купчина са групирани в заглавията Създаване, Основни, Вътрешни и Инспекция. Следва резюме на операциите на купчината:
Обобщение на операциите с купчина
Има някои софтуерни операции, които са общи за купчините, както следва:
Създаване на купчина
create_heap: Създаването на купчина означава формиране на обект, който представлява купчината. На езика C можете да създадете купчина с типа обект struct. Един от членовете на структурата ще бъде масивът от купчини. Останалите членове ще бъдат функции (операции) за купчината. Create_heap означава създаване на празна купчина.
Heapify: масивът от купчина е частично сортиран (подреден) масив. Heapify означава, предоставете масив от купчина от несортиран масив - вижте подробности по-долу.
Обединяване: Това означава, образувайте обединена купчина от две различни купчини - вижте подробности по-долу. Двете купчини трябва да са max-heap или и двете min-heap. Новата купчина е в съответствие със свойствата на купчината, докато оригиналните купчини се запазват (не се изтриват).
Meld: Това означава, съединете две купчини от един и същи тип, за да образувате нов, като поддържате дубликати - вижте подробности по-долу. Новата купчина е в съответствие със свойството на купчината, докато оригиналните купчини са унищожени (изтрити). Основната разлика между сливането и смесването е, че за смесване едното дърво се вписва като поддърво към корена на другото дърво, което позволява дублиране на стойности в новото дърво, докато за сливането се формира ново дърво на купчина, премахвайки дубликати. Не е необходимо да се поддържат двете оригинални купчини с преливане.
Основни операции с купчина
find_max (find_min): Намерете максималната стойност в масива max-heap и върнете копие или намерете минималната стойност в масива min-heap и върнете копие.
Вмъкване: Добавете нов елемент към масива от купчини и пренаредете масива, така че да се поддържа свойството на купчината на диаграмата.
extract_max (extract_min): Намерете максималната стойност в масива max-heap, премахнете и върнете; или намерете минималната стойност в масива min-heap, премахнете го и го върнете.
delete_max (delete_min): Намерете основния възел на max-heap, който е първият елемент от масива max-heap, премахнете го, без да го връщате непременно; или намерете основния възел на min-heap, който е първият елемент от масива min-heap, премахнете го, без да го връщате непременно;
Замяна: Намерете основния възел на която и да е купчина, премахнете го и го заменете с нов. Няма значение дали старият корен се връща.
Вътрешни операции с купчина
увеличение_ключ (намаляване_ключ): Увеличете стойността на който и да е възел за max-heap и пренаредете така, че да се поддържа свойството heap, или намалете стойността на който и да е възел за min-heap и пренаредете така, че свойството heap да се поддържа.
Изтриване: изтрийте всеки възел, след това пренаредете, така че свойството на купчината да се поддържа за max-heap или min-heap.
shift_up: преместете възел нагоре в max-heap или min-heap толкова дълго, колкото е необходимо, пренареждане, за да поддържате свойството heap.
shift_down: преместване на възел надолу в max-heap или min-heap толкова дълго, колкото е необходимо, пренареждане, за да се поддържа свойството heap.
Инспекция на купчина
Размер: Това връща броя ключове (стойности) в купчина; не включва празните местоположения на масива от купчини. Купчината може да бъде представена чрез код, както е на диаграмата, или с масив.
празно е: Това връща Boolean true, ако няма възел в купчина, или Boolean false, ако купчината има поне един възел.
Пресяване на куп
Има пресяване и пресяване надолу:
Пресяване: Това означава да замените възел с неговия родител. Ако свойството на купчината не е удовлетворено, заменете родителя със собствения му родител. Продължете по този начин по пътя, докато свойството на купчината бъде удовлетворено. Процедурата може да достигне до корена.
Пресяване: Това означава да замените възел с голяма стойност с по-малкото от двете му деца (или едно дете за почти пълна купчина). Ако свойството на купчината не е удовлетворено, разменете долния възел с по-малкия възел на собствените му две деца. Продължете по този начин по пътя, докато свойството на купчината бъде удовлетворено. Процедурата може да достигне лист.
Утежняващо
Heapify означава сортиране на несортиран масив, за да бъде удовлетворено свойството heap за max-heap или min-heap. Това означава, че в новия масив може да има някои празни места. Основният алгоритъм за натрупване на max-heap или min-heap е както следва:
- ако коренният възел е по-екстремен от който и да е от възела на детето си, тогава обменяйте корен с по-малко екстремния възел.
- Повторете тази стъпка с дъщерните възли в схема за преминаване на дърво за предварителна поръчка.
Крайното дърво е дърво на купчина, отговарящо на свойството на купчината. Купчината може да бъде представена като дървовидна диаграма или в масив. Получената купчина е частично сортирано дърво, т.е.д. частично сортиран масив.
Подробности за операцията с купчини
Този раздел на статията дава подробности за операциите по купчина.
Създаване на подробности за купчината
create_heap
Виж по-горе!
натрупвам
Виж по-горе
сливане
Ако масивите от купчината,
89, 85, 87, 84, 82, 79, 73, 80, 81,,, 65, 69и
89, 85, 84, 73, 79, 80, 83, 65, 68, 70, 71са обединени, резултатът без дубликати може да бъде,
89, 85, 87, 84, 82, 83, 81, 80, 79,, 73, 68, 65, 69, 70, 71След известно пресяване. Забележете, че в първия масив 82 няма деца. В получения масив той е с индекс 4; и неговите местоположения при индекс 2 (4) + 1 = 9 и 2 (4) + 2 = 10 са свободни. Това означава, че той също няма деца в новата дървовидна диаграма. Оригиналните две купчини не трябва да се изтриват, тъй като информацията им всъщност не е в новата купчина (нов масив). Основният алгоритъм за обединяване на купчини от същия тип е както следва:
- Присъединете единия масив към дъното на другия масив.
- Heapify премахва дубликати, като се уверява, че възлите, които не са имали деца в оригиналните купчини, все още нямат деца в новата купчина.
мелд
Алгоритъмът за смесване на две купчини от един и същи тип (или две макси- или две мин-) е както следва:
- Сравнете двата коренни възла.
- Направете по-малко екстремния корен и останалото дърво (поддърво), второто дете на крайния корен.
- Пресейте бездомното дете на корена на сегашното крайно поддърво, надолу в крайното поддърво.
Получената купчина все още е в съответствие със свойството на купчината, докато оригиналните купчини са унищожени (изтрити). Оригиналните купчини могат да бъдат унищожени, тъй като цялата информация, която те притежават, все още е в новата купчина.
Основни операции с купчина
find_max (find_min)
Това означава да намерите максималната стойност в масива max-heap и да върнете копие или да намерите минималната стойност в масива min-heap и да върнете копие. Масивът на купчина по дефиниция вече удовлетворява свойството на купчината. Така че, просто върнете копие на първия елемент от масива.
вмъкване
Това означава да добавите нов елемент към масива от купчини и да пренаредите масива, така че свойството на купчината на диаграмата да се поддържа (удовлетворено). Алгоритъмът за това и за двата вида купчини е както следва:
- Да приемем пълно двоично дърво. Това означава, че масивът трябва да се запълни в края с празни места, ако е необходимо. Общият брой възли на пълна купчина е 1, или 3, или 7, или 15, или 31 и т.н.; продължете да удвоявате и добавяте 1.
- Поставете възела в най-подходящото празно място по величина, към края на купчината (към края на масива от купчини). Ако няма празно място, започнете нов ред отдолу вляво.
- Пресейте, ако е необходимо, докато свойството на купчината бъде удовлетворено.
екстракт_макс (екстракт_мин)
Намерете максималната стойност в масива max-heap, премахнете и върнете; или намерете минималната стойност в масива min-heap, премахнете го и го върнете. Алгоритъмът за extract_max (extract_min) е както следва:
- Премахнете основния възел.
- Вземете (премахнете) най-долния десен възел (последния възел в масива) и поставете в корена.
- Пресейте, както е подходящо, докато свойството на купчината бъде удовлетворено.
delete_max (delete_min)
Намерете основния възел на max-heap, който е първият елемент от масива max-heap, премахнете го, без да го връщате непременно; или намерете кореновия възел на min-heap, който е първият елемент от масива min-heap, премахнете го, без да го връщате непременно. Алгоритъмът за изтриване на коренния възел е както следва:
- Премахнете основния възел.
- Вземете (премахнете) най-долния десен възел (последния възел в масива) и поставете в корена.
- Пресейте, както е подходящо, докато свойството на купчината бъде удовлетворено.
замени
Намерете коренния възел на която и да е купчина, премахнете го и го заменете с новия. Няма значение дали старият корен се връща. Пресейте, ако е подходящо, докато свойството на купчината бъде удовлетворено.
Вътрешни операции с купчина
увеличение_ключ (намаляване_клавиша)
Увеличете стойността на който и да е възел за max-heap и пренаредете така, че да се поддържа свойството heap или намалете стойността на който и да е възел за min-heap и пренаредете така, че да се поддържа свойството heap. Пресейте нагоре или надолу, както е подходящо, докато свойството на купчината бъде удовлетворено.
Изтрий
Премахнете интересуващия възел, след това пренаредете, така че свойството на купчината да се поддържа за max-heap или min-heap. Алгоритъмът за изтриване на възел е както следва:
- Премахнете интересуващия възел.
- Вземете (премахнете) най-долния десен възел (последния възел в масива) и поставете в индекса на отстранения възел. Ако изтритият възел е на последния ред, това може да не е необходимо.
- Пресейте нагоре или надолу, както е подходящо, докато свойството на купчината бъде удовлетворено.
shift_up
Преместете възел нагоре в max-heap или min-heap толкова дълго, колкото е необходимо, пренареждане, за да поддържате свойството на купчината - пресейте.
shift_down
Преместете възел надолу в max-heap или min-heap толкова дълго, колкото е необходимо, пренареждане, за да поддържате свойството на купчината - пресейте надолу.
Инспекция на купчина
размер
Виж по-горе!
празно е
Виж по-горе!
Други класове купчини
Купчината, описана в тази статия, може да се счита за основна (обща) купчина. Има и други класове купчини. Двете, които трябва да знаете отвъд това, са двоичната купчина и дневната купчина.
Двоична купчина
Двоичната купчина е подобна на тази основна купчина, но с повече ограничения. По-специално, двоичната купчина трябва да е пълно дърво. Не бъркайте между пълно дърво и пълно дърво.
d-ary Heap
Двоична купчина е 2-арна купчина. Купчина, в която всеки възел има по 3 деца, е 3-арна купчина. Купчина, където всеки възел има по 4 деца, е 4-арна купчина и т.н. Реалната купчина има и други ограничения.
Заключение
Купчината е пълно или почти пълно двоично дърво, което удовлетворява свойството купчина. Свойството heap има 2 алтернативи: за max-heap родителят трябва да бъде равен или по-голям по стойност от непосредствените деца; за минимална купчина родителят трябва да бъде равен или по-малък по стойност от непосредствените деца. Купчината може да бъде представена като дърво или в масив. Когато е представен в масив, коренният възел е първият възел на масива; и ако възел е с индекс n, първото му дете в масива е с индекс 2n + 1, а следващото му дете е с индекс 2n + 2. Куп има определени операции, които се извършват върху масива.
Chrys