C++STL中堆的实现

使用 make_heap() 创建的堆可以提供一些 priority_queue 没有的优势:

  1. 可以访问堆中的任意元素,而不限于最大的元素,因为元素被存储在一个容器中,就像是我们自己的 vector。这也提供了偶然破坏元素顺序的可能,但是总可以调用 make_heap() 来还原堆。
  2. 可以在任何提供随机访问迭代器的序列容器中创建堆。这些序列容器包括普通数组、string 对象、自定义容器。这意味着无论什么时候需要,都可以用这些序列容器的元素创建堆,必要时,可以反复创建。甚至还可以为元素的子集创建堆。

<1>为了向堆中添加元素,首先可以用任何方法将元素附加到序列中。然后调用 push_heap() 来插入最后一个元素,为了保持堆的结构,这个元素会被重新排列到一个适当的位置。

std::vector<double> numbers {2.5, 10.0, 3.5, 6.5, 8.0, 12.0, 1.5, 6.0};
std::make_heap(std::begin(numbers),std::end(numbers));
// Result: 12 10 3.5 6.5 8 2.5 1.5 6
numbers.push_back(11); // Result: 12 10 3.5 6.5 8 2.5 1.5 6 11
std::push_heap(std::begin(numbers), std::end(numbers));
// Result: 12 11 3. 5 10 8 2. 5 1. 5 6 6. 5

也可以用自己的比较函数来创建堆,但是必须和 push_heap() 使用相同的比较函数:

std::vector<double> numbers {2.5, 10.0, 3.5, 6.5, 8.0, 12.0, 1.5, 6.0};
std::make_heap(std::begin(numbers), std::end(numbers),
std::greater<>());//Result: 1.5 6 2.5 6.5 8 12 3.5 10 numbers. push—back(1. 2);
//Result: 1.5 6 2.5 6.5 8 12 3.5 10 1.2
std::push_heap(std::begin(numbers), std::end(numbers),std::greater<>());
//Result: 1.2 1.5 2.5 6 8 12 3.5 10 6.5

<2> 删除最大元素和添加元素到堆的过程有些相似,但所做的事是相反的。首先调用 pop_heap(),然后从容器中移除最大的元素,例如:

std::vector<double> numbers{2.5, 10.0, 3.5, 6.5, 8.0, 12.0, 1.5, 6.0};
std::make_heap(std::begin(numbers),std::end(numbers));
//Result:12 10 3.5 6.5 8 2.5 1.5 6
std::pop_heap(std::begin(numbers),std::end(numbers));
// Result:10 8 3.5 6.5 6 2.5 1.5 12
numbers.pop_back();// Result:10 8 3.5 6.5 6 2.5 1.5

<3>此外, STL 提供了一个检查序列是否仍然是堆的方法:

if(std::is_heap(std::begin(numbers),std::end(numbers)))
    std::cout << "Great! We still have a heap.\n";
else
    std::cout << "oh bother! We messed up the heap.\n";

 <4>STL 提供的最后一个操作是 sort_heap(),它会将元素段作为堆来排序。如果元素段不是堆,程序会在运行时崩溃。这个函数有以两个迭代器为参数的版本,迭代器指向一个假定的大顶堆(用 less<> 排列),然后将堆中的元素排成降序。结果当然不再是大顶堆。下面是一个使用它的示例:

std::vector<double> numbers {2.5, 10.0, 3.5, 6.5, 8.0, 12.0, 1.5, 6.0};
std::make_heap(std::begin(numbers), std::end(numbers));
//Result: 12 10 3.5 6.5 8 2.5 1.5 6
std::sort_heap(std::begin(numbers), std::end(numbers));
// Result: 1.5 2.5 3.5 6 6.5 8 10 12

实例代码: 

#include <iostream>
#include<algorithm>
#include<vector>
#include<functional>
using namespace std;
void show(const double &n)
{
   cout<<n<<" ";
}
int main()
{
    vector<double>num(8);
    cout<<"please input eight number:";
    for(int i=0;i<8;i++)
    cin>>num.at(i);
    make_heap(num.begin(),num.end(),greater<double>());
    sort_heap(num.begin(),num.end(),greater<double>());//堆排序
    for_each(num.begin(),num.end(),show);
    cout<<endl;
    num.push_back(7);
    push_heap(num.begin(),num.end(),less<double>());
    sort_heap(num.begin(),num.end(),less<double>());
    for_each(num.begin(),num.end(),show);
    cout<<endl;
    pop_heap(num.begin(),num.end(),less<double>());
    num.pop_back();
    sort_heap(num.begin(),num.end(),less<double>());
    for_each(num.begin(),num.end(),show);
    cout<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43871369/article/details/88530200