STLRecipe---heap

2019-08-15  本文已影响0人  世界上的一道风

创建堆

用来创建堆的函数定义在头文件 algorithm 中。max_heap() 对随机访问迭代器指定的一段元素重新排列,生成一个堆。默认使用的是 < 运算符,可以生成一个大顶堆。例如:

int main()
{
    vector<double>numbers{2.5,10.0,3.5,6.5,8.0,12.0,1.5,6.0};
    make_heap(numbers.begin(), numbers.end());
    for(auto i:numbers)
        cout<< i << " ";
}
12 10 3.5 6.5 8 2.5 1.5 6  
image.png

priority_queue 是一个堆。在底层,一个 priority_queue实例创建了一个堆。在堆中,所有成对的连续元素不需要有相同的比较关系。既然如此,为什么 STL 有 priority_queue (它是一个堆),却还需要创建堆,特别是还需要将堆作为优先级队列?

从另一方面来说,使用 make_heap()创建的堆可以提供一些 priority_queue `没有的优势:

这里有另一个版本的 make_heap(),它有第 3 个参数,可以用来指定一个比较函数用于堆的排序。通过定义一个大于运算符函数,可以生成一个小顶堆。这里可以使用functional中的断言。例如:

int main()
{
    vector<double>numbers{2.5,10.0,3.5,6.5,8.0,12.0,1.5,6.0};
    make_heap(begin(numbers), end(numbers),greater<>());
    for(auto i:numbers)
        cout<< i << " ";
}
1.5 6 2.5 6.5 8 12 3.5 10 

可以将模板类型参数指定为greater。这里的这个尖括号为空的版本推断并返回了类型参数。已经有一个用 make_heap()函数在容器中生成的堆。可以在它上面进行很多操作,下面我们来深入了解这些操作。

堆操作

//push_back() 会在序列末尾添加元素,然后使用 push_heap() 恢复堆的排序。

int main()
{
    vector<double>numbers{2.5,10.0,3.5,6.5,8.0,12.0,1.5,6.0};
    make_heap(numbers.begin(), numbers.end());
    numbers.push_back(11);
    for(auto i:numbers)
        cout<< i << " ";
    cout << endl;
    push_heap(begin(numbers),end(numbers));
    for(auto i:numbers)
        cout<< i << " ";
    cout << endl;
}

12 10 3.5 6.5 8 2.5 1.5 6 11 
12 11 3.5 10 8 2.5 1.5 6 6.5 

int main()
{
    vector<double>numbers{2.5,10.0,3.5,6.5,8.0,12.0,1.5,6.0};
    make_heap(numbers.begin(), numbers.end());
    for(auto i:numbers)
        cout<< i << " ";
    cout << endl;
    pop_heap(begin(numbers),end(numbers));
    for(auto i:numbers)
        cout<< i << " ";
    cout << endl;
    numbers.pop_back();
    for(auto i:numbers)
        cout<< i << " ";
    cout << endl;    
}

12 10 3.5 6.5 8 2.5 1.5 6 
10 8 3.5 6.5 6 2.5 1.5 12 
10 8 3.5 6.5 6 2.5 1.5 
cout<<"is heap: " << is_heap(begin(numbers), end(numbers)) << endl;
is heap: 1

注意:创建堆用的什么断言,操作的时候就用同样断言,如greater<>less<>

int main()
{
    vector<double>numbers{2.5, 10.0, 3.5, 6.5, 8.0, 12.0, 1.5, 6.0};
    make_heap(numbers.begin(), numbers.end(),greater<>());
    for(auto i:numbers)
        cout<< i << " ";
    cout << endl;
    pop_heap(begin(numbers),end(numbers), greater<>());
    for(auto i:numbers)
        cout<< i << " ";
    cout << endl;
    auto iter = std::is_heap_until(std::begin(numbers),std::end(numbers),std::greater<>());
    if(iter != std::end(numbers))
    std::cout << "numbers is a heap up to "<<*iter <<std::endl;
}

1.5 6 2.5 6.5 8 12 3.5 10 
2.5 6 3.5 6.5 8 12 10 1.5 
numbers is a heap up to 1.5
int main()
{
    vector<double>numbers{2.5, 10.0, 3.5, 6.5, 8.0, 12.0, 1.5, 6.0};
    make_heap(numbers.begin(), numbers.end(),greater<>());
    for(auto i:numbers)
        cout<< i << " ";
    cout << endl;
    sort_heap(begin(numbers),end(numbers), greater<>());
    for(auto i:numbers)
        cout<< i << " ";
    cout << endl;
}

1.5 6 2.5 6.5 8 12 3.5 10 
12 10 8 6.5 6 3.5 2.5 1.5 

例子:太长了请参考reference

参数不需要指定为 `const`,但最好这样做。在任何情况下,比较函数都不能改变传给它的参数值。
    // Find length of longest string
    auto max_len = std::max_element(std::begin(words), std::end(words),
                                  [](const string& s1, const string& s2)
                                  {return s1.size() < s2.size(); })->size();
类似于
bool comp(const T1& a,const T2& b);

上一篇 下一篇

猜你喜欢

热点阅读