-
最大ヒープ、最小ヒープ
最大ヒープ: 各ノードの子ノードはノードより小さい
最小ヒープ: 各ノードの子ノードはノードより大きいヒープは完全なバイナリ ツリーなので、
- ヒープ内のノードに
i
左右の子ノードがある場合、
左の子ノード:i x 2 + 1
右の子ノード:i x 2 + 2
- ヒープ内のノードに
j
親がある場合、
親:(j-1)/2
-
最大ヒープを作成します。
- 最後の非リーフ ノードからルート ノードまでのヒープを調整します。
- 特定のノードをルートとしてヒープを調整します
a. 子ノードがそのノードより大きい場合は、左右の子ノードの中で最大のノードとノードを交換し、その子ノードを調整します b. それ以外の場合は
、調整する必要はありません
c. 葉ノードになるまで、または調整が必要なくなるまで、このプロセスを繰り返します。
void AdjustHeap(std::vector<int> & heap, int cur, int length) { int left = cur * 2 + 1, right = cur * 2 + 2; int large = cur; if (left < length && heap[left] > heap[large]) { large = left; } if (right < length && heap[right] > heap[large]) { large = right; } if (large != cur) { std::swap(heap[large], heap[cur]); AdjustHeap(heap, large, length); } } //从最后的非叶子节点开始调整堆,一直到根节点 void buildHeap(std::vector<int> & data) { for(int i = (data.size() - 1 - 1)>> 1; i >= 0; i--) { AdjustHeap(data, i, data.size()); } }
-
AdjustHeap の非再帰的な方法:
- ループを使用して、現在のノードが適切な位置を見つけるまで、調整する必要がある各子ノードを見つけます。
void AdjustHeap_NotRec(std::vector<int> & heap, int cur, int length) { int large = cur; for (int child = cur * 2 + 1; child < length; child = cur * 2 + 1) { if (heap[child] > heap[large]) { large = child; } child++; if (child < length && heap[child] > heap[large]) { large = child; } if (large != cur) { std::swap(heap[large], heap[cur]); cur = large; } else { break; } } }
-
ヒープソート:
- 各ルートノードと最終ノードを交換し、最終ノード以外のデータを最大ヒープに調整します
void sortHeap(std::vector<int> & data) { int length = data.size(); for(int i = data.size() - 1; i >= 0; i--) { std::swap(data[i], data[0]); AdjustHeap(data, 0, length - 1); --length; } }
ps: k 番目の最大値を探している場合は、for ループの条件を次のように設定できます: i > data.size() - k で、data[0] を返します。
-
ヒープにノードを追加します。
- データにノードを追加する
- ノードを上に調整し、そのノードをできるだけルートに近づけて交換します
void pushHeap(std::vector<int> & data, int num) { data.push_back(num); int cur = data.size() - 1; for (int parent = (cur - 1) >> 1; parent >= 0; parent = parent >> 1) { if (data[cur] > data[parent]) { std::swap(data[cur], data[parent]); cur = parent; } else { break; } } }
-
検証済みのメイン:
int main(int argc, char * argv[]) { std::vector<int> data = { 3, 2, 3, 1, 2, 4, 5, 5, 6}; buildHeap(data); pushHeap(data, 8); sortHeap(data); for(auto & num : data) { std::cout << num << " "; } std::cout << std::endl; return 0; }
出力:
1 2 2 3 3 4 5 5 6 8
- ヒープ内のノードに
-
優先キュー
C++ では、
priority_queue
最大ヒープまたは最小ヒープは、優先キュー クラスを通じて管理できます。
そのヘッダー ファイルは<queue>
次のように定義されています。
priority_queue<T, Container, std::less<T>>
最大のヒープ
priority_queue<T, Container, std::greater<T>>
は最小のヒープです。#include <iostream> #include <queue> #include <vector> template<typename T> void print_queue(T q) { while(!q.empty()) { std::cout << q.top() << " "; q.pop(); } std::cout << std::endl; } int main(int argc, char * argv[]) { const auto data = { 3, 2, 3, 1, 2, 4, 5, 5, 6}; std::priority_queue<int, std::vector<int>, std::less<int>> q1; for (auto & num : data) { q1.push(num); } print_queue(q1); // another init way std::priority_queue<int, std::vector<int>, std::less<int>> q2(data.begin(), data.end()); print_queue(q2); // using lambda to compare elements auto cmp = [](int left, int right) { return left < right;}; std::priority_queue<int, std::vector<int>, decltype(cmp)> q3(data.begin(), data.end(), cmp); print_queue(q3); return 0; }
出力は次のとおりです。
6 5 5 4 3 3 2 2 1 6 5 5 4 3 3 2 2 1 6 5 5 4 3 3 2 2 1
https://en.cppreference.com/w/cpp/container/priority_queue
最大ヒープ、最小ヒープ、priority_queue
おすすめ
転載: blog.csdn.net/iamanda/article/details/116562934
おすすめ
ランキング