STL——Heap算法

本文详细介绍了C++ STL中与Heap相关的算法,包括make_heap、push_heap、pop_heap和sort_heap的功能、使用场景及其时间复杂度。make_heap用于将元素转化为heap,push_heap用于在已有的heap中添加元素,pop_heap则将最大元素移出heap,sort_heap将heap转换为已排序序列。所有操作都需要确保输入元素满足heap性质。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STL——heap算法

1、就排序而言,heap是一种特别的元素组织方式,应用于heap排序法(heapsort)。Heap可被视为一个以序列式集合实现而成的二叉树,具有两大性质:
(1)第一个元素总是最大。
(2)总是能够在对数时间内增加或移除一个元素。

2、STL中提供了4个算法:默认的排序准则是 operator<,也可以传入一个binary predicate 作为排序准则。

(1)make_heap():将某个区间内的元素转化为heap;

void make_heap(RandomAccessIterator beg, RandomAccessIterator end)
void make_heap(RandomAccessIterator beg, RandomAccessIterator end, BinaryPredicate op)

  • 两种形式都将[beg,end)区间内的元素转化为heap。
  • op是个可有可无的(可选的)binary predicate,被视为排序准则,op(elem1,elem2)
  • 只有在多于一个元素的情况下,才有必要使用这些函数处理heap,如果只有单一元素,那么它自动形成一个heap。
  • 复杂度:线性,至多执行3*numElems次比较。
(2)push_heap():对heap增加一个元素;

void push_heap(RandomAccessIterator beg, RandomAccessIterator end)
void push_heap(RandomAccessIterator beg, RandomAccessIterator end, BinaryPredicate op)
  • 两种形式都将end之前的最后一个元素加入原本就是heap的[beg,end-1)区间内,是整个[beg,end)区间成为一个heap。
  • op是个可有可无的(可选的)binary predicate,被视为排序准则,op(elem1,elem2)。
  • 调用者必须保证,在进入函数时,[beg,end-1)区间内的元素原本便已形成一个heap,而新元素紧跟其后。
  • 复杂度:对数,至多执行log(numElems)次比较。
(3)pop_heap():对heap取出下一个元素;

void pop_heap(RandomAccessIterator beg, RandomAccessIterator end)
void pop_heap(RandomAccessIterator beg, RandomAccessIterator end, BinaryPredicate op)
  • 以上两种形式都将heap[beg,end)内的最高元素(也就是第一个元素)移到最后位置,并将剩余区间[beg,end-1)内的元素组成一个新的heap。
  • op是个可有可无的(可选的)binary predicate,被视为排序准则,op(elem1,elem2)。
  • 调用者必须保证,在进入函数时,[beg,end)区间内的元素原本便已形成一个heap。
  • 复杂度:对数,至多执行2*log(numElems)次比较。
(4)sort_heap():将heap转化为一个已排序群集(此后它就不再是heap了)。

void sort_heap(RandomAccessIterator beg, RandomAccessIterator end)
void sort_heap(RandomAccessIterator beg, RandomAccessIterator end, BinaryPredicate op)
  • 以上两种形式都可以将heap[beg,end)转换为一个已排序序列。
  • op是个可有可无的(可选的)binary predicate,被视为排序准则,op(elem1,elem2)。
  • 注意,此算法一旦结束,该区间就不再是个heap了。
  • 调用者必须保证,在进入函数时,[beg,end)区间内的元素原本便已形成一个heap。
  • 复杂度:nlogn,最多执行numElems*log(numElems)次比较。
Heap算法使用示例:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
       vector<int> vec{ 1,2,3,4,7,8,5,6,9,0 };
       for (auto x : vec)
              cout << x << " ";
       cout << endl;

       make_heap(vec.begin(), vec.end());         //将某区间内的元素转化为heap
       cout << "after make_heap(): ";
       for (auto x : vec)
              cout << x << " ";
       cout << endl;

       vec.push_back(4);
       push_heap(vec.begin(), vec.end());          //对heap增加一个元素
       cout << "after push_heap(): ";
       for (auto x:vec)
              cout << x << " ";
       cout << endl;

       pop_heap(vec.begin(), vec.end());           //对heap减少一个元素
       cout << "after pop_heap() : ";
       for (auto x : vec)
              cout << x << " ";
       cout << endl;

       sort_heap(vec.begin(), vec.end()-1);       //对[beg,end-1)区间内的元素进行排序,之后就不再是heap
       cout << "after sort_heap(): ";
       for (auto x : vec)
              cout << x << " ";
       cout << endl;
       return 0;
}

运行结果:




参考:Nicolai M,Josuttis. 侯捷译. C++标准库(第2版)[M].北京:电子工业出版社,2015:604-607.

make_heap、push_heap、pop_heap和sort_heap都是C++ STL库中的算法,用于操作堆(heap)数据结构。 1. make_heap:将一个无序的区间转换为堆。函数原型如下: ``` template <class RandomAccessIterator> void make_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其中,first和last分别为区间的起始和结束迭代器。make_heap函数会将[first,last)区间转换为堆。调用该函数后,该区间的最大元素会被放在第一个位置上。 2. push_heap:将一个元素添加到堆中。函数原型如下: ``` template <class RandomAccessIterator> void push_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其中,first和last分别为区间的起始和结束迭代器。当前,[first,last-1)已经是一个堆,push_heap函数将last-1位置的元素添加到堆中,并且保证该堆仍然是一个堆。 3. pop_heap:将堆的最大元素移动到末尾。函数原型如下: ``` template <class RandomAccessIterator> void pop_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其中,first和last分别为区间的起始和结束迭代器。当前,[first,last)已经是一个堆,pop_heap函数将该堆的最大元素(即first位置的元素)移动到last-1位置,并且保证[first,last-1)仍然是一个堆。 4. sort_heap:将一个堆排序。函数原型如下: ``` template <class RandomAccessIterator> void sort_heap (RandomAccessIterator first, RandomAccessIterator last); ``` 其中,first和last分别为区间的起始和结束迭代器。当前,[first,last)已经是一个堆,sort_heap函数会将该堆转换为有序序列。 需要注意的是,这几个函数都要求操作的区间是一个随机访问迭代器(RandomAccessIterator)类型的迭代器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值