-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHeap.cpp
More file actions
97 lines (81 loc) · 3.97 KB
/
Copy pathHeap.cpp
File metadata and controls
97 lines (81 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "Heap.hpp"
#include <iostream>
bool Heap::isLess(const Node& a, const Node& b) { // Porównuje dwa elementy na podstawie priorytetu i identyfikatora wstawienia
if (a.priority != b.priority) {
return a.priority < b.priority; // Porównuje priorytety
}
return a.insertion_id > b.insertion_id; // Jeśli priorytety są równe, porównuje identyfikatory wstawienia
}
void Heap::heapifyUp(int i) { // Przesuwa element w górę kopca, aby zachować właściwość kopca
while (i > 0 && isLess(heap[parent(i)], heap[i])) { // Dopóki element nie jest korzeniem i jego priorytet jest większy niż priorytet rodzica
heap.swap(i, parent(i)); // Jeśli priorytet jest większy, zamienia je miejscami
i = parent(i); // Przechodzi do indeksu rodzica
}
}
void Heap::heapifyDown(int i) { // Przesuwa element w dół kopca, aby zachować właściwość kopca
int largest = i;
int left = leftChild(i);
int right = rightChild(i);
if (left < heapSize && isLess(heap[largest], heap[left])) {
largest = left; // Jeśli lewe dziecko ma większy priorytet, aktualizuje największy indeks
}
if (right < heapSize && isLess(heap[largest], heap[right])) {
largest = right; // Jeśli prawe dziecko ma większy priorytet, aktualizuje największy indeks
}
if (largest != i) {
heap.swap(i, largest); // Jeśli największy indeks nie jest równy i, zamienia element z największym dzieckiem
heapifyDown(largest); // Rekurencyjnie wywołuje heapifyDown dla nowego indeksu
}
}
void Heap::printHeap() const { // Pomocnicza funkcja do debugowania, wyświetla zawartość kopca
std::cout << "Heap contents:\n";
for (int i = 0; i < heapSize; i++) {
const auto& node = heap[i];
std::cout << "Value: " << node.value << ", Priority: " << node.priority << ", Insertion ID: " << node.insertion_id << "\n";
}
}
void Heap::insert(const int value, int priority) { // Wstawia nowy element do kopca
heap.pushBack({ value, priority, counter++ }); // Dodaje nowy element do kopca, przypisując mu wartość, priorytet i unikalny identyfikator wstawienia
heapSize++; // Zwiększa rozmiar kopca
heapifyUp(heapSize - 1); // Przesuwa nowy element w górę, aby zachować właściwość kopca
}
int Heap::extract_max() { // Usuwa element o najwyższym priorytecie z kopca
if (heapSize == 0) {
throw std::runtime_error("Heap is empty"); // Rzuca wyjątek, jeśli kopiec jest pusty
}
int max_value = heap[0].value; // Zapisuje wartość elementu o najwyższym priorytecie (korzenia)
heap[0] = heap[heapSize - 1]; // Przenosi ostatni element na miejsce korzenia
heap.popBack(); // Usuwa ostatni element
heapSize--; // Zmniejsza rozmiar kopca
heapifyDown(0); // Przesuwa element w dół, aby zachować właściwość kopca
return max_value; // Zwraca wartość elementu o najwyższym priorytecie
}
const int& Heap::peek() const { // Zwraca element o najwyższym priorytecie bez usuwania go z kopca
if (heapSize == 0) {
throw std::runtime_error("Heap is empty"); // Rzuca wyjątek, jeśli kopiec jest pusty
}
return heap[0].value; // Zwraca wartość elementu o najwyższym priorytecie (korzenia) bez usuwania go z kopca
}
void Heap::modify_key(int value, int newPriority) { // Zmienia priorytet elementu w kopcu
int index = -1;
for (int i = 0; i < heapSize; i++) {
if (heap[i].value == value) { // Szuka elementu o podanej wartości
index = i;
break;
}
}
if (index == -1) {
throw std::runtime_error("modify_key: element not found"); // Rzuca wyjątek, jeśli element o podanej wartości nie został znaleziony
}
int oldPriority = heap[index].priority; // Zapisuje stary priorytet elementu
heap[index].priority = newPriority;
if (newPriority > oldPriority) {
heapifyUp(index); // Jeśli nowy priorytet jest większy, przesuwa element w górę, aby zachować właściwość kopca
}
else if (newPriority < oldPriority) {
heapifyDown(index); // Jeśli nowy priorytet jest mniejszy, przesuwa element w dół, aby zachować właściwość kopca
}
}
int Heap::return_size() const {
return heapSize; // Zwraca rozmiar kopca
}