Làm cách nào để tạo Min stl priority_queue?


110

Hàng đợi ưu tiên stl mặc định là Max một (Hàm trên cùng trả về phần tử lớn nhất).

Nói đơn giản, nó là một hàng đợi ưu tiên của các giá trị int.

Câu trả lời:


189

Sử dụng std::greaterlàm hàm so sánh:

std::priority_queue<int, std::vector<int>, std::greater<int> > my_min_heap;

4
@eriks Bạn có một số tùy chọn. Lớp của bạn xác định operator>, sẽ hoạt động giống như sự quyến rũ với std::greater. Bạn cũng có thể viết functor của riêng bạn thay vì std::greaternếu bạn muốn.
AraK

2
@AraK, tôi nghĩ bạn có nghĩa là operator<;)
Peter Alexander

15
Cần lưu ý rằng để sử dụng std ::
great

3
@CarryonSmiling trong thư viện mẫu chuẩn, các lớp vectordequelớp đáp ứng các yêu cầu mà một vùng chứa bên dưới phải đáp ứng cho một priority_queue. Bạn cũng có thể sử dụng một lớp vùng chứa tùy chỉnh. Bạn có thể tìm thấy lời giải thích tỉ mỉ trên cplusplus.com/reference/queue/priasty_queue
Tanmay Garg

3
Ai đó có thể giải thích tại sao min heap lại sử dụng <int> lớn hơn không <int> không?
Telenoobies

45

Một cách sẽ là xác định một bộ so sánh phù hợp để hoạt động trên hàng đợi ưu tiên thông thường, sao cho mức độ ưu tiên của nó bị đảo ngược:

 #include <iostream>  
 #include <queue>  
 using namespace std;  

 struct compare  
 {  
   bool operator()(const int& l, const int& r)  
   {  
       return l > r;  
   }  
 };  

 int main()  
 {  
     priority_queue<int,vector<int>, compare > pq;  

     pq.push(3);  
     pq.push(5);  
     pq.push(1);  
     pq.push(8);  
     while ( !pq.empty() )  
     {  
         cout << pq.top() << endl;  
         pq.pop();  
     }  
     cin.get();  
 }

Mà sẽ xuất ra 1, 3, 5, 8 tương ứng.

Một số ví dụ về việc sử dụng hàng đợi ưu tiên thông qua triển khai STL và Sedgewick được đưa ra ở đây .


1
Bạn có thể vui lòng giải thích tại sao chúng tôi sử dụng l> r chứ không phải l <r, để thực hiện hàng đợi ưu tiên tối thiểu không?
Dhruv Mullick

3
Bộ so sánh mặc định cho hàng đợi ưu tiên là l <r. Bạn có thể thấy điều đó trong tham số mặc định của hàm tạo . Bằng cách làm l> r hoặc r <l, bạn sẽ nhận được điều ngược lại.
Diaa

1
@AndyUK Xin chào, ¿tại sao bạn sử dụng cấu trúc để triển khai toán tử so sánh? cảm ơn trước
AER

Hàng đợi ưu tiên mặc định trong C ++ là hàng đợi ưu tiên tối đa.
qwr

30

Tham số mẫu thứ ba cho priority_queuelà bộ so sánh. Đặt nó để sử dụng greater.

ví dụ

std::priority_queue<int, std::vector<int>, std::greater<int> > max_queue;

Bạn sẽ cần phải #include <functional>cho std::greater.


@Potatoswatter: không phải lúc nào cũng vậy.
Moha con lạc đà toàn năng

11
Đây là tốt hơn so với các câu trả lời được chấp nhận bởi vì nó cũng đề cập đến #include <chức năng>
reggaeguitar

22

Bạn có thể thực hiện theo nhiều cách:
1. Sử dụng greaterlàm hàm so sánh:

 #include <bits/stdc++.h>

using namespace std;

int main()
{
    priority_queue<int,vector<int>,greater<int> >pq;
    pq.push(1);
    pq.push(2);
    pq.push(3);

    while(!pq.empty())
    {
        int r = pq.top();
        pq.pop();
        cout<<r<< " ";
    }
    return 0;
}

2. Chèn các giá trị bằng cách thay đổi dấu của chúng (sử dụng dấu trừ (-) cho số dương và sử dụng cộng (+) cho số âm:

int main()
{
    priority_queue<int>pq2;
    pq2.push(-1); //for +1
    pq2.push(-2); //for +2
    pq2.push(-3); //for +3
    pq2.push(4);  //for -4

    while(!pq2.empty())
    {
        int r = pq2.top();
        pq2.pop();
        cout<<-r<<" ";
    }

    return 0;
}

3. Sử dụng cấu trúc hoặc lớp tùy chỉnh:

struct compare
{
    bool operator()(const int & a, const int & b)
    {
        return a>b;
    }
};

int main()
{

    priority_queue<int,vector<int>,compare> pq;
    pq.push(1);
    pq.push(2);
    pq.push(3);

    while(!pq.empty())
    {
        int r = pq.top();
        pq.pop();
        cout<<r<<" ";
    }

    return 0;
}

4. Sử dụng cấu trúc hoặc lớp tùy chỉnh, bạn có thể sử dụng priority_queue theo bất kỳ thứ tự nào. Giả sử, chúng ta muốn sắp xếp mọi người theo thứ tự giảm dần theo mức lương của họ và nếu hòa thì theo tuổi của họ.

    struct people
    {
        int age,salary;

    };
    struct compare{
    bool operator()(const people & a, const people & b)
        {
            if(a.salary==b.salary)
            {
                return a.age>b.age;
            }
            else
            {
                return a.salary>b.salary;
            }

    }
    };
    int main()
    {

        priority_queue<people,vector<people>,compare> pq;
        people person1,person2,person3;
        person1.salary=100;
        person1.age = 50;
        person2.salary=80;
        person2.age = 40;
        person3.salary = 100;
        person3.age=40;


        pq.push(person1);
        pq.push(person2);
        pq.push(person3);

        while(!pq.empty())
        {
            people r = pq.top();
            pq.pop();
            cout<<r.salary<<" "<<r.age<<endl;
    }
  1. Có thể thu được kết quả tương tự bằng cách nạp chồng toán tử:

    struct people
    {
    int age,salary;
    
    bool operator< (const people & p)const
    {
        if(salary==p.salary)
        {
            return age>p.age;
        }
        else
        {
            return salary>p.salary;
        }
    }};
    

    Trong chức năng chính:

    priority_queue<people> pq;
    people person1,person2,person3;
    person1.salary=100;
    person1.age = 50;
    person2.salary=80;
    person2.age = 40;
    person3.salary = 100;
    person3.age=40;
    
    
    pq.push(person1);
    pq.push(person2);
    pq.push(person3);
    
    while(!pq.empty())
    {
        people r = pq.top();
        pq.pop();
        cout<<r.salary<<" "<<r.age<<endl;
    }
    

Bạn không có nghĩa là bool operator > (const people & p)const trong vòng 5) điều hành quá tải
Rockstar5645

1
Trên thực tế, phải không bạn, 5) không làm việc, nó chỉ là lạ, tôi chưa bao giờ nhìn thấy <quá tải như thế, nó tốt hơn để tình trạng quá tải >và sử dụnggreater<people>
Rockstar5645

19

Trong C ++ 11, bạn cũng có thể tạo một bí danh để thuận tiện:

template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T>>;

Và sử dụng nó như thế này:

min_heap<int> my_heap;

8

Một cách để giải quyết vấn đề này là, đẩy giá trị âm của mỗi phần tử trong hàng ưu tiên để phần tử lớn nhất sẽ trở thành phần tử nhỏ nhất. Tại thời điểm thực hiện thao tác pop, hãy thực hiện phủ định của từng phần tử.

#include<bits/stdc++.h>
using namespace std;

int main(){
    priority_queue<int> pq;
    int i;

// push the negative of each element in priority_queue, so the largest number will become the smallest number

    for (int i = 0; i < 5; i++)
    {
        cin>>j;
        pq.push(j*-1);
    }

    for (int i = 0; i < 5; i++)
    {
        cout<<(-1)*pq.top()<<endl;
        pq.pop();
    }
}

3

Dựa trên tất cả các câu trả lời, tôi đã tạo một mã ví dụ về cách tạo hàng đợi ưu tiên. Lưu ý: Nó hoạt động với trình biên dịch C ++ 11 trở lên

#include <iostream>
#include <vector>
#include <iomanip>
#include <queue>

using namespace std;

// template for prirority Q
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T>>;
template<class T> using max_heap = priority_queue<T, std::vector<T>>;

const int RANGE = 1000;

vector<int> get_sample_data(int size);

int main(){
  int n;
  cout << "Enter number of elements N = " ; cin >> n;
  vector<int> dataset = get_sample_data(n);

  max_heap<int> max_pq;
  min_heap<int> min_pq;

  // Push data to Priority Queue
  for(int i: dataset){
    max_pq.push(i);
    min_pq.push(i);
  }

  while(!max_pq.empty() && !min_pq.empty()){
    cout << setw(10) << min_pq.top()<< " | " << max_pq.top() << endl;
    min_pq.pop();
    max_pq.pop();
  }

}


vector<int> get_sample_data(int size){
  srand(time(NULL));
  vector<int> dataset;
  for(int i=0; i<size; i++){
    dataset.push_back(rand()%RANGE);
  }
  return dataset;
}

Đầu ra của mã trên

Enter number of elements N = 4

        33 | 535
        49 | 411
       411 | 49
       535 | 33

1

Chúng ta có thể làm điều này bằng một số cách.

Sử dụng tham số so sánh mẫu

    int main() 
    {
      priority_queue<int, vector<int>, greater<int> > pq;

      pq.push(40);
      pq.push(320);
      pq.push(42);
      pq.push(65);
      pq.push(12);

      cout<<pq.top()<<endl;
      return 0;
    }

Sử dụng lớp trình biên dịch đã định nghĩa đã sử dụng

     struct comp
     {
        bool operator () (int lhs, int rhs)
        {
           return lhs > rhs;
        }
     };

    int main()
    {
       priority_queue<int, vector<int>, comp> pq;

       pq.push(40);
       pq.push(320);
       pq.push(42);
       pq.push(65);
       pq.push(12);

       cout<<pq.top()<<endl;

       return 0;
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.