大顶堆,小顶堆--优先队列,示例

在C++中,std::priority_queue 默认实现的是一个大顶堆(Max-Heap),

其中每个父节点的值都大于或等于其子节点的值。

然而,通过指定第三个模板参数为比较函数或函数对象,可以改变这一默认行为。

 

 

std::priority_queue<int, std::vector<int>, std::greater<int>> heap;

这里使用了 std::greater<int> 作为比较函数对象。

std::greater<int> 是一个标准库提供的函数对象,它对于两个整数 a 和 b,如果 a 小于 b,则返回 true(即 a < b)。

因此,当使用 std::greater<int> 作为 std::priority_queue 的比较函数时,堆的行为将变为小顶堆(Min-Heap),其中每个父节点的值都小于或等于其子节点的值。

所以,这段代码创建的是一个小顶堆。

 

 

问题:

有一个数组,要求找出最大的3个数,最小的4个数。

 

小顶堆,从小到大排序(greater 比较函数 | 'a<b' ),堆顶元素最小,筛选最小的N个数。

    // 创建一个小顶堆
    std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;

 

 

大顶堆,从大到小排序,(less 比较函数 | 'a>b'),筛选最大的N个数。

 // 创建一个大顶堆
    std::priority_queue<int, std::vector<int>, std::less<int>> max_heap;
复制代码
    小顶堆:
         1
       /   \
      3     2
     / \   / \
    7   8 5   4

    大顶堆:
         8
       /   \
      7     5
     / \   / \
    3   1 2   4
复制代码

 

小顶堆和大顶堆都是二叉堆的一种形式,是一种用于实现优先队列的数据结构。它们的区别在于元素的排列方式和根节点的值。

  1. 小顶堆(Min Heap):在小顶堆中,每个节点的值都小于或等于其子节点的值。换句话说,堆顶元素是最小值,根节点的值小于其左右子节点的值。小顶堆的性质使得堆顶元素是优先级最低的。

  2. 大顶堆(Max Heap):在大顶堆中,每个节点的值都大于或等于其子节点的值。换句话说,堆顶元素是最大值,根节点的值大于其左右子节点的值。大顶堆的性质使得堆顶元素是优先级最高的。

在小顶堆中,根节点的值最小,且每个节点的值都小于或等于其子节点的值。而在大顶堆中,根节点的值最大,且每个节点的值都大于或等于其子节点的值

 

复制代码
#include <iostream>
#include <vector>
#include <queue>

// 定义一个函数来创建小顶堆并筛选出最小的 4 个数
std::vector<int> findFourSmallestNumbers(const std::vector<int>& nums) {
    // 创建一个小顶堆
    std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;

    // 将数组中的元素插入到小顶堆中
    for (int i = 0; i< nums.size(); ++i) {
        min_heap.push(nums[i]);
    }

    // 从堆中依次取出最小的 4 个数
    std::vector<int> result;
    for (int i = 0; i < 4; ++i) {
        result.push_back(min_heap.top());
        min_heap.pop();
    }

    return result;
}

// 定义一个函数来创建大顶堆并筛选出最大的 3 个数
std::vector<int> findThreeLargestNumbers(const std::vector<int>& nums) {
    // 创建一个大顶堆
    std::priority_queue<int, std::vector<int>, std::less<int>> max_heap;

    // 将数组中的元素插入到大顶堆中
    for (int i = 0; i < nums.size(); ++i) {
        max_heap.push(nums[i]);
    }

    // 从堆中依次取出最大的 3 个数
    std::vector<int> result;
    for (int i = 0; i < 3; ++i) {
        result.push_back(max_heap.top());
        max_heap.pop();
    }

    return result;
}

int main() {
    std::vector<int> nums = {3, 1, 4, 10, 5, 19, 22, 60, 5, 38, 5, 8, 999, 7, 9, 31, 2};

    // 找到最小的 4 个数
    std::vector<int> fourSmallestNumbers = findFourSmallestNumbers(nums);
    std::cout << "最小的 4 个数: ";
    for (int num : fourSmallestNumbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 找到最大的 3 个数
    std::vector<int> threeLargestNumbers = findThreeLargestNumbers(nums);
    std::cout << "最大的 3 个数: ";
    for (int num : threeLargestNumbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}
复制代码

 

 

from chat-gpt:

复制代码
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

void findLargestAndSmallest(vector<int> &nums) {
    // Min heap
    priority_queue<int, vector<int>, greater<int>> minHeap;
    // Max heap
    priority_queue<int> maxHeap;

    // Push all elements to both heaps
    for (int num : nums) {
        minHeap.push(num);
        maxHeap.push(num);
    }

    // Find the largest 3 numbers
    cout << "Largest 3 numbers: ";
    for (int i = 0; i < 3; ++i) {
        cout << maxHeap.top() << " ";
        maxHeap.pop();
    }
    cout << endl;

    // Find the smallest 4 numbers
    cout << "Smallest 4 numbers: ";
    for (int i = 0; i < 4; ++i) {
        cout << minHeap.top() << " ";
        minHeap.pop();
    }
    cout << endl;
}

int main() {
    // Example array of 20 integers (random)
    vector<int> nums = {12, 34, 56, 78, 90, 23, 45, 67, 89, 10, 32, 54, 76, 98, 21, 43, 65, 87, 9, 87};

    findLargestAndSmallest(nums);

    return 0;
}
复制代码

 

posted @   He_LiangLiang  阅读(398)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2023-03-03 mysql中union的用法
点击右上角即可分享
微信分享提示