📜  堆 c++ stl - C++ (1)

📅  最后修改于: 2023-12-03 15:23:41.184000             🧑  作者: Mango

堆 C++ STL - C++

在C++中,堆是一种非常有用的数据结构。C++的STL(标准模板库)提供了一个非常方便的堆实现。堆是一种优先队列,可以快速找到最大或最小元素。在本文中,我们将深入介绍堆的定义、STL中的堆实现以及一些示例代码。

堆的定义

堆是一种基于完全二叉树的数据结构,其中每个节点的值都大于或等于(或小于或等于)其子节点的值。因此,堆可以被分为两种类型: 最大堆和最小堆。在最大堆中,每个节点的值都大于或等于其子节点的值,而在最小堆中,每个节点的值都小于或等于其子节点的值。

C++ STL中的堆

在C++的STL中,堆是由 #include <queue> 头文件中的 std::priority_queue 类模板实现的。默认情况下, priority_queue 实现的是最大堆,但是我们可以通过传递比较函数对象来创建最小堆。

创建最大堆

最大堆可以通过不传递比较函数对象来创建。以下是创建最大堆的示例代码:

#include <iostream>
#include <queue>

int main() {
    std::priority_queue<int> max_heap;

    max_heap.push(35);
    max_heap.push(23);
    max_heap.push(42);
    max_heap.push(17);

    std::cout << "Top element of max heap: " << max_heap.top() << "\n";

    max_heap.pop();
    std::cout << "Top element after popping: " << max_heap.top() << "\n";

    return 0;
}

在上面的示例代码中,我们使用 std::priority_queue<int> 来创建一个最大堆。我们向堆中添加一些元素,然后使用 top() 函数找到堆的顶部元素。我们可以使用 pop() 删除堆的顶部元素。最后,该程序将输出以下结果:

Top element of max heap: 42
Top element after popping: 35
创建最小堆

要创建最小堆,我们必须传递一个比较函数对象来告诉堆如何比较元素。以下是创建最小堆的示例代码:

#include <iostream>
#include <queue>

struct greater {
    template<class T>
    bool operator()(T const& a, T const& b) const {
        return a > b;
    }
};

int main() {
    std::priority_queue<int, std::vector<int>, greater> min_heap;

    min_heap.push(35);
    min_heap.push(23);
    min_heap.push(42);
    min_heap.push(17);

    std::cout << "Top element of min heap: " << min_heap.top() << "\n";

    min_heap.pop();
    std::cout << "Top element after popping: " << min_heap.top() << "\n";

    return 0;
}

在上面的示例代码中,我们使用具有比较函数对象的 std::priority_queue<int, std::vector<int>, greater> 来创建一个最小堆。比较函数对象 greater 会告诉堆如何比较元素。我们向堆中添加一些元素,然后使用 top() 函数找到堆的顶部元素。我们可以使用 pop() 删除堆的顶部元素。最后,该程序将输出以下结果:

Top element of min heap: 17
Top element after popping: 23
堆的一些示例代码
找到第k大的元素

以下示例代码使用最小堆找到第k大的元素:

#include <iostream>
#include <queue>
#include <vector>

int kth_largest_element(std::vector<int>& vec, int k) {
    std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;
    
    for (int i = 0; i < k; i++) {
        min_heap.push(vec[i]);
    }
    
    for (int i = k; i < vec.size(); i++) {
        if (vec[i] > min_heap.top()) {
            min_heap.pop();
            min_heap.push(vec[i]);
        }
    }

    return min_heap.top();
}

int main() {
    std::vector<int> vec = {5, 2, 8, 7, 1};
    int k = 3;

    int kth_largest = kth_largest_element(vec, k);

    std::cout << "Kth largest element: " << kth_largest << "\n";

    return 0;
}

在上面的示例代码中,我们使用了一个最小堆,只保留了前k个元素。随着向堆中添加更多元素,我们可以使用 top() 函数找到最小值并且将其删除。最后,我们返回堆的顶部元素,它将是第k大的元素。以上代码将输出以下结果:

Kth largest element: 5
排序

以下示例代码使用最小堆来排序:

#include <iostream>
#include <queue>
#include <vector>

std::vector<int> heap_sort(std::vector<int>& vec) {
    std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;

    for (int i = 0; i < vec.size(); i++) {
        min_heap.push(vec[i]);
    }

    std::vector<int> result;
    while (!min_heap.empty()) {
        result.push_back(min_heap.top());
        min_heap.pop();
    }
    return result;
}

int main() {
    std::vector<int> vec = {5, 2, 8, 7, 1};

    std::vector<int> sorted_vec = heap_sort(vec);

    std::cout << "Sorted array: ";
    for (auto element : sorted_vec) {
        std::cout << element << " ";
    }
    std::cout << "\n";

    return 0;
}

在上面的示例代码中,我们使用最小堆对向量进行排序。我们首先将向量的元素添加到堆中,然后将堆中的元素取出并添加到另一个向量中。最后,我们返回排序后的向量。以上代码将输出以下结果:

Sorted array: 1 2 5 7 8 
结论

堆是一个非常有用的数据结构,C++的STL通过 priority_queue 类模板提供了非常方便的堆实现。我们可以使用最小堆来找到第k大的元素、排序等。

我们希望本文能够帮助你更深入地理解堆的定义以及C++ STL中的堆实现。