【C++之泛型算法】016Heap算法

make_heap()

make_heap 是 C++ 标准库 中提供的一个函数,用于将一个给定的范围(例如数组或向量)转换为一个堆(heap)。特别地,它通常用于创建最大堆。
泛型声明

make_heap 的泛型声明如下:

template< class RandomIt >
void make_heap( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
void make_heap( RandomIt first, RandomIt last, Compare comp );

其中:

  • RandomIt 是一个随机访问迭代器类型,用于指定输入范围的开始和结束。
  • first 和 last 分别指向输入范围的开始和结束。
  • Compare 是一个可选的比较函数或函数对象,用于定义堆的排序规则。如果未提供,则使用 < 操作符进行默认比较。

具体用法

下面是一个简单的例子,展示如何使用 make_heap:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // 创建一个向量
    std::vector<int> v = {4, 1, 3, 9, 7, 2, 8, 5, 6};

    // 使用 make_heap 将向量转换为最大堆
    std::make_heap(v.begin(), v.end());

    // 输出堆中的元素
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,make_heap 将向量 v 转换为一个最大堆。因此,堆顶元素(即向量中的第一个元素)将是最大的元素。

如果你想使用自定义的比较函数来定义堆的排序规则,可以这样做:

#include <iostream>
#include <vector>
#include <algorithm>

// 自定义比较函数
bool my_compare(int a, int b) {
    return a < b; // 这将创建一个最小堆
}

int main() {
    std::vector<int> v = {4, 1, 3, 9, 7, 2, 8, 5, 6};

    // 使用自定义比较函数将向量转换为最小堆
    std::make_heap(v.begin(), v.end(), my_compare);

    // 输出堆中的元素
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,make_heap 使用 my_compare 函数来创建一个最小堆。

push_heap()

push_heap 是 C++ 标准库 中提供的一个函数,用于将一个元素插入到已有的堆中,并重新调整堆以保持其性质。如果堆是使用 make_heap 创建的,则可以使用 push_heap 来在堆的末尾添加新元素,并确保堆的性质得到维护。
泛型声明

push_heap 的泛型声明如下:

template< class RandomIt >
void push_heap( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
void push_heap( RandomIt first, RandomIt last, Compare comp );

其中:

  • RandomIt 是一个随机访问迭代器类型,用于指定堆的范围。
  • first 和 last 分别指向堆的范围的开始和结束。
  • Compare 是一个可选的比较函数或函数对象,用于定义堆的排序规则。如果未提供,则使用 < 操作符进行默认比较。

具体用法

下面是一个使用 push_heap 的例子:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // 创建一个向量并转换为最大堆
    std::vector<int> v = {4, 1, 3, 9, 7, 2, 8, 5, 6};
    std::make_heap(v.begin(), v.end());

    // 输出初始堆中的元素
    std::cout << "Initial heap: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 在堆的末尾插入一个新元素
    v.push_back(10);
    std::push_heap(v.begin(), v.end());

    // 输出更新后堆中的元素
    std::cout << "Heap after pushing 10: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,我们首先使用 make_heap 将向量 v 转换为一个最大堆。然后,我们在向量的末尾添加一个新元素 10,并使用 push_heap 来重新调整堆,确保堆的性质得到维护。因此,新元素 10 会被放置在正确的位置上,以保持堆是一个最大堆。

如果你想要使用自定义的比较函数来定义堆的排序规则,你可以像下面这样做:

#include <iostream>
#include <vector>
#include <algorithm>

// 自定义比较函数
bool my_compare(int a, int b) {
    return a < b; // 这将创建一个最小堆
}

int main() {
    std::vector<int> v = {4, 1, 3, 9, 7, 2, 8, 5, 6};

    // 使用自定义比较函数创建最小堆
    std::make_heap(v.begin(), v.end(), my_compare);

    // 在堆的末尾插入一个新元素并重新调整堆
    v.push_back(10);
    std::push_heap(v.begin(), v.end(), my_compare);

    // 输出更新后堆中的元素
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,push_heap 使用 my_compare 函数来确保堆保持最小堆的性质。

pop_heap()

pop_heap 是 C++ 标准库 中提供的一个函数,用于从堆中移除并返回堆顶元素(即最大或最小元素,取决于堆的性质),然后重新调整堆以保持其性质。如果堆是使用 make_heap 创建的,则可以使用 pop_heap 来移除堆顶元素,并确保剩余的堆元素仍然保持堆的性质。
泛型声明

pop_heap 的泛型声明如下:

template< class RandomIt >
void pop_heap( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
void pop_heap( RandomIt first, RandomIt last, Compare comp );

其中:

  • RandomIt 是一个随机访问迭代器类型,用于指定堆的范围。
  • first 和 last 分别指向堆的范围的开始和结束。
  • Compare 是一个可选的比较函数或函数对象,用于定义堆的排序规则。如果未提供,则使用 < 操作符进行默认比较。

具体用法

下面是一个使用 pop_heap 的例子:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // 创建一个向量并转换为最大堆
    std::vector<int> v = {4, 1, 3, 9, 7, 2, 8, 5, 6};
    std::make_heap(v.begin(), v.end());

    // 输出初始堆中的元素
    std::cout << "Initial heap: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 移除并返回堆顶元素(最大元素)
    int top_element = std::pop_heap(v.begin(), v.end());
    std::cout << "Removed top element: " << top_element << std::endl;

    // 输出移除堆顶元素后的堆
    std::cout << "Heap after popping top element: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,我们首先使用 make_heap 将向量 v 转换为一个最大堆。然后,我们使用 pop_heap 来移除并返回堆顶元素(即最大元素),并将剩余的堆元素重新调整为最大堆。因此,pop_heap 之后,堆顶元素(即向量中的第一个元素)将是剩余元素中的最大元素。

如果你想使用自定义的比较函数来定义堆的排序规则,可以像下面这样做:

#include <iostream>
#include <vector>
#include <algorithm>

// 自定义比较函数
bool my_compare(int a, int b) {
    return a < b; // 这将创建一个最小堆
}

int main() {
    std::vector<int> v = {4, 1, 3, 9, 7, 2, 8, 5, 6};

    // 使用自定义比较函数创建最小堆
    std::make_heap(v.begin(), v.end(), my_compare);

    // 输出初始堆中的元素
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 移除并返回堆顶元素(最小元素)
    int top_element = std::pop_heap(v.begin(), v.end(), my_compare);
    std::cout << "Removed top element: " << top_element << std::endl;

    // 输出移除堆顶元素后的堆
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,pop_heap 使用 my_compare 函数来确保堆保持最小堆的性质,并移除并返回最小的元素。

sort_heap()

sort_heap 是 C++ 标准库 中提供的一个函数,用于将堆(heap)中的元素进行排序。堆是一种特殊的完全二叉树结构,通常使用数组来表示,其中每个父节点的值都大于或等于(对于最大堆)或小于或等于(对于最小堆)其子节点的值。sort_heap 函数会利用堆的性质,以线性时间复杂度将堆中的元素转换为有序序列。
泛型声明

sort_heap 的泛型声明如下:

template< class RandomIt >
void sort_heap( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
void sort_heap( RandomIt first, RandomIt last, Compare comp );

其中:

  • RandomIt 是一个随机访问迭代器类型,用于指定堆的范围。
  • first 和 last 分别指向堆的范围的开始和结束。
  • Compare 是一个可选的比较函数或函数对象,用于定义堆的排序规则。如果未提供,则使用 < 操作符进行默认比较。

具体用法

下面是一个使用 sort_heap 的例子:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // 创建一个向量并转换为最大堆
    std::vector<int> v = {4, 1, 3, 9, 7, 2, 8, 5, 6};
    std::make_heap(v.begin(), v.end());

    // 输出初始堆中的元素
    std::cout << "Initial heap: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 将堆排序
    std::sort_heap(v.begin(), v.end());

    // 输出排序后的堆(现在是一个有序序列)
    std::cout << "Sorted heap: ";
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,我们首先使用 make_heap 将向量 v 转换为一个最大堆。然后,我们使用 sort_heap 对堆进行排序,使其成为一个有序序列。sort_heap 会保持堆的性质直到整个序列都变得有序,因此它可以在 O(N) 的时间复杂度内完成排序,其中 N 是堆中元素的数量。排序后,堆中的元素将以升序排列(对于默认的比较操作 <)。

如果你想要使用自定义的比较函数来定义排序规则,可以像下面这样做:

#include <iostream>
#include <vector>
#include <algorithm>

// 自定义比较函数
bool my_compare(int a, int b) {
    return a < b; // 这将创建一个最小堆,并且排序后也是升序排列
}

int main() {
    std::vector<int> v = {4, 1, 3, 9, 7, 2, 8, 5, 6};

    // 使用自定义比较函数创建最大堆
    std::make_heap(v.begin(), v.end(), my_compare);

    // 输出初始堆中的元素
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 将堆排序
    std::sort_heap(v.begin(), v.end(), my_compare);

    // 输出排序后的堆
    for (const auto& num : v) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个例子中,我们使用了自定义的比较函数 my_compare 来创建一个最小堆,并且排序后也是升序排列。如果你想要降序排列,你可以在比较函数中交换 a 和 b 的位置。

  • 33
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊猫Devin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值