diff --git a/codes/cpp/chapter_heap/heap.cpp b/codes/cpp/chapter_heap/heap.cpp new file mode 100644 index 000000000..38171c8d3 --- /dev/null +++ b/codes/cpp/chapter_heap/heap.cpp @@ -0,0 +1,66 @@ +/** + * File: heap.cpp + * Created Time: 2023-01-19 + * Author: LoneRanger(836253168@qq.com) + */ + +#include "../include/include.hpp" + +void testPush(priority_queue &heap, int val) +{ + heap.push(val); // 元素入堆 + cout << "元素 " << val << " 入堆后" << endl; + PrintUtil::printHeap(heap); +} +void testPoll(priority_queue &heap) +{ + int val = heap.top(); + heap.pop(); + cout << "堆顶元素 " << val << " 出堆后" << endl; + PrintUtil::printHeap(heap); +} + +int main() +{ + /* 初始化堆 */ + // 初始化小顶堆 + // priority_queue, greater> minHeap; + // 初始化大顶堆 + priority_queue, less> maxHeap; + + cout << "以下测试样例为大顶堆" << endl; + + /* 元素入堆 */ + testPush(maxHeap, 1); + testPush(maxHeap, 3); + testPush(maxHeap, 2); + testPush(maxHeap, 5); + testPush(maxHeap, 4); + + /* 获取堆顶元素 */ + int peek = maxHeap.top(); + cout << "堆顶元素为: " << peek << endl; + + /* 堆顶元素出堆 */ + testPoll(maxHeap); + testPoll(maxHeap); + testPoll(maxHeap); + testPoll(maxHeap); + testPoll(maxHeap); + + /* 获取堆大小 */ + int size = maxHeap.size(); + cout << "堆元素数量为: " << size << endl; + + /* 判断堆是否为空 */ + bool isEmpty = maxHeap.empty(); + cout << "堆是否为空: " << isEmpty << endl; + + /* 输入列表并建堆 */ + // 时间复杂度为 O(n) ,而非 O(nlogn) + vector input{1, 3, 2, 5, 4}; + priority_queue, greater> minHeap(input.begin(), input.end()); + cout << "输入列表并建立小顶堆后" << endl; + PrintUtil::printHeap(minHeap); + return 0; +} diff --git a/codes/cpp/include/PrintUtil.hpp b/codes/cpp/include/PrintUtil.hpp index e788d1650..56583e15b 100644 --- a/codes/cpp/include/PrintUtil.hpp +++ b/codes/cpp/include/PrintUtil.hpp @@ -13,6 +13,27 @@ #include "ListNode.hpp" #include "TreeNode.hpp" +/** + * @brief Expose the underlying storage of the priority_queue container + * + * @tparam T + * @tparam S + * @tparam C + * @param pq + * @return S + */ +template +S &Container(priority_queue &pq) { + struct HackedQueue : private priority_queue + { + static S &Container(priority_queue &pq) + { + return pq.*&HackedQueue::c; + } + }; + return HackedQueue::Container(pq); +} + class PrintUtil { public: /** @@ -293,4 +314,22 @@ class PrintUtil { cout << kv.first << " -> " << kv.second << '\n'; } } + + /** + * @brief Print a Heap (PriorityQueue) + * + * @tparam T + * @tparam S + * @tparam C + * @param heap + */ + template + static void printHeap(priority_queue &heap) { + vector vec = Container(heap); + cout << "堆的数组表示:" << endl; + printVector(vec); + cout << "堆的树状表示:" << endl; + TreeNode *root = vecToTree(vec); + printTree(root); + } }; diff --git a/docs/chapter_heap/heap.md b/docs/chapter_heap/heap.md index 62d093c29..555aad236 100644 --- a/docs/chapter_heap/heap.md +++ b/docs/chapter_heap/heap.md @@ -85,7 +85,39 @@ comments: true === "C++" ```cpp title="heap.cpp" + /* 初始化堆 */ + // 初始化小顶堆 + priority_queue, greater> minHeap; + // 初始化大顶堆 + priority_queue, less> maxHeap; + + /* 元素入堆 */ + maxHeap.push(1); + maxHeap.push(3); + maxHeap.push(2); + maxHeap.push(5); + maxHeap.push(4); + /* 获取堆顶元素 */ + int peek = maxHeap.top(); // 5 + + /* 堆顶元素出堆 */ + // 出堆元素会形成一个从大到小的序列 + maxHeap.pop(); // 5 + maxHeap.pop(); // 4 + maxHeap.pop(); // 3 + maxHeap.pop(); // 2 + maxHeap.pop(); // 1 + + /* 获取堆大小 */ + int size = maxHeap.size(); + + /* 判断堆是否为空 */ + bool isEmpty = maxHeap.empty(); + + /* 输入列表并建堆 */ + vector input{1, 3, 2, 5, 4}; + priority_queue, greater> minHeap(input.begin(), input.end()); ``` === "Python"