📜  如何使用STL实现Min Heap?

📅  最后修改于: 2021-05-30 06:55:42             🧑  作者: Mango

在C++ STL中,存在priority_queue可直接用于实现Max Heap。为了完全理解代码,请确保您熟悉C++中的以下概念

  • STL中的容器适配器
  • 函子

请参见以下示例:

CPP
// C++ program to show that priority_queue is by
// default a Max Heap
#include 
using namespace std;
 
// Driver code
int main ()
{
    // Creates a max heap
    priority_queue  pq;
    pq.push(5);
    pq.push(1);
    pq.push(10);
    pq.push(30);
    pq.push(20);
 
    // One by one extract items from max heap
    while (pq.empty() == false)
    {
        cout << pq.top() << " ";
        pq.pop();
    }
 
    return 0;
}


CPP
// C++ program to use priority_queue to implement min heap
#include 
using namespace std;
 
// Driver code
int main ()
{
    // Creates a min heap
    priority_queue , greater > pq;
    pq.push(5);
    pq.push(1);
    pq.push(10);
    pq.push(30);
    pq.push(20);
 
    // One by one extract items from min heap
    while (pq.empty() == false)
    {
        cout << pq.top() << " ";
        pq.pop();
    }
 
    return 0;
}


C++
// C++ Progrma to implement min heap
// using default priority_queue(max-heap)
 
#include 
#include 
using namespace std;
 
int main()
{
    // data
    int arr[] = { 25, 7, 9, 15, 20, 36, 50 };
   
      // default priority_queue using max-heap
    priority_queue pq;
   
      // size of the array
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // multiply -1 with all elements while
    // inserting
    for (int i = 0; i < n; i++) {
        pq.push((-1) * arr[i]);
    }
 
    // multiply all elements with -1 while
    // retrive the elements
    while (!pq.empty()) {
        cout << (pq.top()) * (-1) << " ";
        pq.pop();
    }
 
    return 0;
}


CPP
// C++ program to use priority_queue to implement Min Heap
// for user defined class
#include 
using namespace std;
 
// User defined class, Point
class Point
{
   int x;
   int y;
public:
   Point(int _x, int _y)
   {
      x = _x;
      y = _y;
   }
   int getX() const { return x; }
   int getY() const { return y; }
};
 
// To compare two points
class myComparator
{
public:
    int operator() (const Point& p1, const Point& p2)
    {
        return p1.getX() > p2.getX();
    }
};
 
// Driver code
int main ()
{
    // Creates a Min heap of points (order by x coordinate)
    priority_queue , myComparator > pq;
 
    // Insert points into the min heap
    pq.push(Point(10, 2));
    pq.push(Point(2, 1));
    pq.push(Point(1, 5));
 
    // One by one extract items from min heap
    while (pq.empty() == false)
    {
        Point p = pq.top();
        cout << "(" << p.getX() << ", " << p.getY() << ")";
        cout << endl;
        pq.pop();
    }
 
    return 0;
}


输出
30 20 10 5 1 

 
由于元素是按降序打印的,因此默认情况下我们有一个最大堆。如何实现Min Heap?
priority_queue支持一个构造函数,该构造函数需要两个额外的参数才能使其成为最小堆。

priority_queue , ComparisonType > min_heap;

第三个参数“比较类型”可以是必须具有bool作为返回类型且必须具有2个参数的函数或因子(aka函数对象)。

以下是整数的示例。

CPP

// C++ program to use priority_queue to implement min heap
#include 
using namespace std;
 
// Driver code
int main ()
{
    // Creates a min heap
    priority_queue , greater > pq;
    pq.push(5);
    pq.push(1);
    pq.push(10);
    pq.push(30);
    pq.push(20);
 
    // One by one extract items from min heap
    while (pq.empty() == false)
    {
        cout << pq.top() << " ";
        pq.pop();
    }
 
    return 0;
}

输出 :

1 5 10 20 30 

使用默认的priority_queue进行min-heap的另一种方法:

这在竞争性编程中经常使用。我们首先将所有元素乘以(-1)。然后,我们创建一个最大堆(最大堆是优先级队列的默认值)。当我们访问数据并想打印时,我们只需将这些元素再乘以(-1)。

下面是上述想法的实现:

C++

// C++ Progrma to implement min heap
// using default priority_queue(max-heap)
 
#include 
#include 
using namespace std;
 
int main()
{
    // data
    int arr[] = { 25, 7, 9, 15, 20, 36, 50 };
   
      // default priority_queue using max-heap
    priority_queue pq;
   
      // size of the array
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // multiply -1 with all elements while
    // inserting
    for (int i = 0; i < n; i++) {
        pq.push((-1) * arr[i]);
    }
 
    // multiply all elements with -1 while
    // retrive the elements
    while (!pq.empty()) {
        cout << (pq.top()) * (-1) << " ";
        pq.pop();
    }
 
    return 0;
}
输出
7 9 15 20 25 36 50 

如何制作用户定义类的最小堆?

让我们考虑下面的示例,在该示例中,我们构建了按X轴排序的2个D点的最小堆。

CPP

// C++ program to use priority_queue to implement Min Heap
// for user defined class
#include 
using namespace std;
 
// User defined class, Point
class Point
{
   int x;
   int y;
public:
   Point(int _x, int _y)
   {
      x = _x;
      y = _y;
   }
   int getX() const { return x; }
   int getY() const { return y; }
};
 
// To compare two points
class myComparator
{
public:
    int operator() (const Point& p1, const Point& p2)
    {
        return p1.getX() > p2.getX();
    }
};
 
// Driver code
int main ()
{
    // Creates a Min heap of points (order by x coordinate)
    priority_queue , myComparator > pq;
 
    // Insert points into the min heap
    pq.push(Point(10, 2));
    pq.push(Point(2, 1));
    pq.push(Point(1, 5));
 
    // One by one extract items from min heap
    while (pq.empty() == false)
    {
        Point p = pq.top();
        cout << "(" << p.getX() << ", " << p.getY() << ")";
        cout << endl;
        pq.pop();
    }
 
    return 0;
}

输出 :

(1, 5)
(2, 1)
(10, 2)
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”