📜  C++ STL中的堆| make_heap(),push_heap(),pop_heap(),sort_heap(),is_heap,is_heap_until()(1)

📅  最后修改于: 2023-12-03 14:39:52.913000             🧑  作者: Mango

C++ STL中的堆

堆是一种数据结构,支持快速的插入和删除操作,并且具有优先级关系。在C++ STL中,堆被封装成了一个容器——heap。heap支持make_heap(), push_heap(), pop_heap(), sort_heap(), is_heap(), is_heap_until()等函数,下面将依次介绍这些函数。

make_heap()

make_heap()可以将一个容器变成堆。调用make_heap()时只需要提供容器的起始地址和结束地址即可,它会自动将容器中的元素按照堆的要求进行调整。

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

using namespace std;

int main()
{
    vector<int> vec{1, 3, 2, 4, 5};
    make_heap(vec.begin(), vec.end());
    for(auto i : vec)
        cout << i << " ";
    return 0;
}

输出:

5 4 2 1 3 

此时,vec就已经变成了一个堆。需要注意的是,每次调用make_heap()都会重新调整堆的结构,因此在往容器中添加或删除元素后需要再次调用make_heap()。

push_heap()

push_heap()可以将一个元素加入到堆中,并保持堆的性质。调用push_heap()时需要提供容器的起始地址和结束地址,以及要插入的元素。

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

using namespace std;

int main()
{
    vector<int> vec{1, 3, 2, 4, 5};
    make_heap(vec.begin(), vec.end());
    vec.push_back(6);
    push_heap(vec.begin(), vec.end());
    for(auto i : vec)
        cout << i << " ";
    return 0;
}

输出:

6 4 5 1 3 2 

在将6插入到vec中之后,调用push_heap()将它加入到堆中。

pop_heap()

pop_heap()可以将堆中的最大元素移除,并保持堆的性质。调用pop_heap()需要提供容器的起始地址和结束地址,它会将堆顶的元素和堆的最后一个元素交换位置,并将堆的大小减一。

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

using namespace std;

int main()
{
    vector<int> vec{1, 3, 2, 4, 5};
    make_heap(vec.begin(), vec.end());
    pop_heap(vec.begin(), vec.end());
    vec.pop_back();
    for(auto i : vec)
        cout << i << " ";
    return 0;
}

输出:

4 3 2 1 

在将vec的最大元素移除后,调用pop_back()将它从容器中删除。需要注意的是,pop_heap()只能移除最大元素,因此如果想要移除其他元素,需要先对元素进行排序。

sort_heap()

sort_heap()可以对堆中的元素进行排序。调用sort_heap()需要提供容器的起始地址和结束地址,它会将堆中的元素按照升序排序。

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

using namespace std;

int main()
{
    vector<int> vec{1, 3, 2, 4, 5};
    make_heap(vec.begin(), vec.end());
    sort_heap(vec.begin(), vec.end());
    for(auto i : vec)
        cout << i << " ";
    return 0;
}

输出:

1 2 3 4 5 

需要注意的是,sort_heap()并不会将容器变成堆,因此如果想要对堆进行排序,需要先调用make_heap()。

is_heap()

is_heap()可以判断一个容器是否为堆。调用is_heap()需要提供容器的起始地址和结束地址,它会返回一个bool类型的值,表示容器是否为堆。

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

using namespace std;

int main()
{
    vector<int> vec{1, 3, 2, 4, 5};
    cout << is_heap(vec.begin(), vec.end()) << endl;
    make_heap(vec.begin(), vec.end());
    cout << is_heap(vec.begin(), vec.end()) << endl;
    return 0;
}

输出:

0
1

在vec还未变成堆时调用is_heap(),返回值为false。在调用make_heap()之后再次调用is_heap(),返回值为true。

is_heap_until()

is_heap_until()可以返回一个迭代器,指向容器中不符合堆性质的第一个元素。调用is_heap_until()需要提供容器的起始地址和结束地址,它会返回一个迭代器,当容器为堆时,迭代器指向容器的结尾。

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

using namespace std;

int main()
{
    vector<int> vec{1, 3, 2, 4, 5};
    auto iter = is_heap_until(vec.begin(), vec.end());
    cout << *iter << endl;
    make_heap(vec.begin(), vec.end());
    iter = is_heap_until(vec.begin(), vec.end());
    cout << *iter << endl;
    return 0;
}

输出:

3
5

在vec还未变成堆时调用is_heap_until(),迭代器指向容器中第一个不符合堆性质的元素,即3。在调用make_heap()之后再次调用is_heap_until(),迭代器指向容器的结尾,即5。