1. 什么是堆(heap)
堆(heap)是一种数据结构,我们可以通过堆,方便的找到数据中最大或最小的数。它的pop_max操作(弹出最大值,整个堆重新heapify)算法复杂度是O(logN)
2. 如何建立一个堆
在c++中已经有建立好的数据结构,方便我们实现堆,堆本质是一种特殊的存储方式,它实质的载体是数组等一些的容器。在c++中调用 #include <queue>中的template <class T, class Container = vector<T>,class Compare = less<typename Container::value_type> > class priority_queue;
比如我们给定一组数[3,2,5,7,9,1],想让这组数构成一个大根堆,每次弹出最大的数:
#include <queue>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char const *argv[]){
    // 创建默认的大根堆
    priority_queue<int> big_heap;
    big_heap.push(3);
    big_heap.push(2);
    big_heap.push(5);
    big_heap.push(7);
    big_heap.push(9);
    big_heap.push(1);
    while( !big_heap.empty()){
        cout << big_heap.top() << " , " ;
        big_heap.pop();
}
return 0;}输出:9 , 7 , 5 , 3 , 2 , 1
在c++中默认的priority_queue就是一个大根堆,如果想要使用小根堆就要把后面的Compare写成greater比较器:
priority_queue<int, std::vector<int>, greater<int>> small_heap;
输出:1 , 2 , 3 , 5 , 7 , 9
3.特殊结构的堆
如果堆中的数据不是直接可以比较的类型(int,double,long),而是一个结构体呢?如果我们不重写Compare,将会出错 error: invalid operands to binary expression ('const student' and 'const student'){return __x < __y;},因为student根本无法比较。
这里我们有两种方法可以改写Compare:
- 重载运算符 operator <
 
# include <queue>
# include <iostream>
# include <string>
#include <vector>
using namespace std;
struct student
{
    int id;
    string name;
    int age;
};
// 直接重载运算符 < 
bool operator< (student a, student b){
     return a.age < b.age;
}
int main(int argc, char const *argv[])
{
    /* code */
    student s1 = {1, "到处露鸟", 26};
    student s2 = {3, "尿尿不洗手", 18};
    student s3 = {2, "便秘女孩", 17};
    //priority_queue<student, std::vector<student>, cmp > students;
    priority_queue<student> students;
    students.push(s1);
    students.push(s3);
    students.push(s2);
    while(!students.empty()){
            cout << students.top().id << ',' << students.top().name << ',' << students.top().age <<endl;
        students.pop();
    }
    return 0;
}输出:按照年龄的大根堆
1,到处露鸟,26
3,尿尿不洗手,18
2,便秘女孩,17
- 用结构体重载 operator()
 
// 结构体重载运算符()
struct cmp
{
    bool operator()(student x, student y){
        return x.age < y.age;
    }
};
int main(int argc, char const *argv[])
{
    /* code */
    student s1 = {1, "到处露鸟", 26};
    student s2 = {3, "尿尿不洗手", 18};
    student s3 = {2, "便秘女孩", 17};
    student s4 = {5, "便秘男孩", 20};
    student s5 = {4, "露屁屁", 28};
    priority_queue<student, std::vector<student>, cmp > students;
    //priority_queue<student> students;
    students.push(s1);
    students.push(s3);
    students.push(s2);
    students.push(s5);
    students.push(s4);
    while(!students.empty()){
        cout << students.top().id << ',' << students.top().name << ',' << students.top().age <<endl;
        students.pop();
    }
    return 0;
}输出:
4,露屁屁,28
1,到处露鸟,26
5,便秘男孩,20
3,尿尿不洗手,18
2,便秘女孩,17
第二种的原因是,在STL中的数据结构的比较是用 operator()定义

京公网安备 11010502036488号