Website Summary Files Commits Branches @commit @diff @stats
path: root / Practicum / pract09
diff options
context:
space:
mode:
Commit36a5f76137ee642768e828ace30359c5e468aa10 (patch)
Author
 Desislava Shunina <115353472+desiish@users.noreply.github.com>
2024-12-04 15:37:37 +0200
Committer
 GitHub <noreply@github.com>
2024-12-04 15:37:37 +0200
Filesfe3d3ef8cb2985721d176b0c4c3c60cfd4c86527 /Practicum/pract09
Data-structures-and-algorithms-36a5f76137ee642768e828ace30359c5e468aa10.tar
Data-structures-and-algorithms-36a5f76137ee642768e828ace30359c5e468aa10.tar.gz
Data-structures-and-algorithms-36a5f76137ee642768e828ace30359c5e468aa10.zip
Parentb40d3e5186af76a278fadfe5bd528f3ea7f5ff01 (diff)
Update readme.md
1 files changed, 57 insertions, 46 deletions
-rw-r--r--Practicum/pract09/readme.md103
diff --git a/Practicum/pract09/readme.md b/Practicum/pract09/readme.md
index 58ee7dd..c55d4fa 100644
--- a/Practicum/pract09/readme.md
+++ b/Practicum/pract09/readme.md
@@ -2,7 +2,7 @@
## `Binary Heap`
**Binary Heap**-a представлява дървовидна структура от данни, която изпълнява 2 условия:
-1) пълно двоично дърво е (всички нива са запълнени освен последното);
+1) пълно двоично дърво е (всички нива са запълнени, освен последното);
2) всеки връх има стойност <= (респективно >=) на тази на родителя си (heap property);
> [!IMPORTANT]
@@ -18,7 +18,7 @@
- `maxHeap` - най-големият елемент е най-отгоре;
### Как от вектор можем да създадем heap?
-STL поддържа методи, които ни позволяват да работим с вектор като с heap. Това са следните:
+STL поддържа методи, които ни позволяват да работим с вектор, като го превърнем в heap. Това са следните:
- **Превръщане на heap**: `std::make_heap(begin_it, end_it)` - O(N)
- **Добавяне на елемент**:
- Добавяме елемент в края на контейнера.
@@ -34,82 +34,93 @@ STL поддържа методи, които ни позволяват да рÐ
#include <vector>
template <typename RandomIt, typename Compare>
-void heapify(RandomIt first, size_t rootIdx, size_t size, Compare comp) {
- size_t largest = rootIdx;
- size_t leftChild = 2 * rootIdx + 1;
- size_t rightChild = 2 * rootIdx + 2;
+void heapify(RandomIt first, RandomIt last, RandomIt root, const Compare& comp) {
+ size_t size = std::distance(first, last);
+ size_t rootIdx = std::distance(first, root);
- if (leftChild < size && comp(*(first + largest), *(first + leftChild)))
- largest = leftChild;
+ while (true) {
+ size_t largest = rootIdx;
+ size_t leftChild = 2 * rootIdx + 1;
+ size_t rightChild = 2 * rootIdx + 2;
- if (rightChild < size && comp(*(first + largest), *(first + rightChild)))
- largest = rightChild;
+ if (leftChild < size && comp(*(first + largest), *(first + leftChild)))
+ largest = leftChild;
+
+ if (rightChild < size&& comp(*(first + largest), *(first + rightChild)))
+ largest = rightChild;
+
+ if (largest == rootIdx)
+ break;
- if (largest != rootIdx) {
std::swap(*(first + rootIdx), *(first + largest));
- heapify(first, largest, size, comp);
+ rootIdx = largest;
}
}
template <typename RandomIt, typename Compare = std::less<>>
void make_heap(RandomIt first, RandomIt last, Compare comp = Compare()) {
- size_t size = last - first; // should use std::dist for when its not vector
+ size_t size = std::distance(first, last);
- for (int i = size / 2; i >= 0; --i)
- heapify(first, i, size, comp);
+ for (int i = (size / 2); i >= 0; --i)
+ heapify(first, last, first + i, comp);
+}
+
+template <typename RandomIt, typename Compare = std::less<>>
+void pop_heap(RandomIt first, RandomIt last, Compare comp = Compare()) {
+ size_t size = std::distance(first, last);
+
+ if (size > 1) {
+ std::swap(*first, *(last - 1));
+ heapify(first, last, first, comp);
+ }
}
template <typename RandomIt, typename Compare>
-void bubble_up(RandomIt first, size_t index, Compare comp) {
- while (index > 0) {
- size_t parentIndex = (index - 1) / 2;
+void bubble_up(RandomIt first, RandomIt last, const Compare& comp) {
+ int childIndex = std::distance(first, last) - 1;
- if (!comp(*(first + parentIndex), *(first + index)))
+ while (childIndex > 0) {
+ int parentIndex = (childIndex - 1) / 2;
+ auto parent = first + parentIndex;
+
+ if (!comp(*parent, *(first + childIndex)))
break;
- std::swap(*(first + parentIndex), *(first + index));
- index = parentIndex;
+ std::swap(*parent, *(first + childIndex));
+ childIndex = parentIndex;
}
}
template <typename RandomIt, typename Compare = std::less<>>
void push_heap(RandomIt first, RandomIt last, Compare comp = Compare()) {
- size_t size = last - first; // should use std::dist for when its not vector
+ size_t size = std::distance(first, last);
- if (size > 1)
- bubble_up(first, size - 1, comp);
+ if (size > 1)
+ bubble_up(first, last, comp);
}
-template <typename RandomIt, typename Compare = std::less<>>
-void pop_heap(RandomIt first, RandomIt last, Compare comp = Compare()) {
- size_t size = last - first; // should use std::dist for when its not vector
+int main()
+{
+ std::vector<int> v = { 1, 9, 2, 5, 3, 15, 6, 98, 10 };
- if (size > 1) {
- std::swap(*first, *(last - 1));
- heapify(first, 0, size - 1, comp);
- }
-}
+ make_heap(v.begin(), v.end());
-template <typename RandomIt, typename Compare = std::less<>>
-bool is_heap(RandomIt first, RandomIt last, Compare comp = Compare()) {
- size_t size = last - first; // should use std:: dist for when its not vector
+ for (auto i : v)
+ std::cout << i << " ";
- for (size_t i = 0; i < size / 2; ++i) {
- size_t leftChild = 2 * i + 1;
- size_t rightChild = 2 * i + 2;
+ pop_heap(v.begin(), v.end());
- if (leftChild < size && comp(*(first + i), *(first + leftChild)))
- return false;
+ for (auto i : v)
+ std::cout << i << " ";
- if (rightChild < size && comp(*(first + i), *(first + rightChild)))
- return false;
- }
+ push_heap(v.begin(), v.end());
- return true;
+ for (auto i : v)
+ std::cout << i << " ";
}
```
-Както се вижда, по default методите използват `std::less<>` за сравнение на обектите, така че default-ния heap е `maxHeap`.
+Както се вижда, по default методите използват `std::less<>` за сравнение на обектите, така че default-ния heap, който ще създадем, е `maxHeap`.
> [!NOTE]
> Ако искаме да създадем `minHeap`, то като comparator трябва да подадем `std::greater<>`.
@@ -189,7 +200,7 @@ public:
И тук, ако искаме да създадем minHeap, трябва да подадем `std::greater<>` като custom comparator.
-### Пример с min-heap
+### Пример за създаване на min-heap
```c++
#include <queue>