मैं मिन स्टाल प्राथमिकता_केयु कैसे बना सकता हूं?


110

डिफ़ॉल्ट stl प्राथमिकता कतार अधिकतम एक है (शीर्ष फ़ंक्शन सबसे बड़ा तत्व देता है)।

कहते हैं, सादगी के लिए, कि यह अंतर मूल्यों की प्राथमिकता कतार है।

जवाबों:


189

std::greaterतुलना फ़ंक्शन के रूप में उपयोग करें :

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

4
@eriks आपके पास कुछ विकल्प हैं। या तो आपके वर्ग को परिभाषित करता है operator>, जो आकर्षण के साथ काम करेगा std::greaterstd::greaterयदि आप चाहें तो आप अपने स्वयं के फ़नकार को भी लिख सकते हैं।
आरा १

2
@ आरा, मुझे लगता है कि आपका मतलब है operator<;)
पीटर अलेक्जेंडर

15
यह ध्यान देने योग्य है कि std का उपयोग करने के लिए :: अधिक से अधिक <int> आपको #include करने की आवश्यकता है <कार्यात्मक>
reggaeguitar

3
@CarryonSmiling मानक टेम्पलेट लाइब्रेरी में, vectorऔर dequeकक्षाएं उन आवश्यकताओं को पूरा करती हैं जो एक अंतर्निहित कंटेनर को प्राथमिकता के लिए मिलना चाहिए। आप एक कस्टम कंटेनर क्लास का भी उपयोग कर सकते हैं। आप cplusplus.com/reference/queue/priority_queue
Tanmay Garg

3
क्या कोई समझा सकता है कि मिन हीप अधिक से अधिक <int> कम नहीं <int> का उपयोग करता है?
तेलीनोबिज़

45

एक तरीका यह होगा कि एक उपयुक्त तुलनित्र को परिभाषित किया जाए, जिसके साथ साधारण प्राथमिकता कतार पर संचालित हो, जैसे कि उसकी प्राथमिकता उलट जाती है:

 #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();  
 }

जो क्रमशः 1, 3, 5, 8 का उत्पादन करेगा।

एसटीएल और सेडगेविक के कार्यान्वयन के माध्यम से प्राथमिकता वाले कतारों का उपयोग करने के कुछ उदाहरण यहां दिए गए हैं


1
क्या आप समझा सकते हैं कि हम न्यूनतम प्राथमिकता कतार को लागू करने के लिए l> r और l <r का उपयोग क्यों नहीं करते हैं?
ध्रुव मुल्लिक

3
प्राथमिकता कतार के लिए डिफ़ॉल्ट तुलनित्र l <r है। आप कंस्ट्रक्टर डिफ़ॉल्ट पैरामीटर में देख सकते हैं । L> r या r <l करने से आपको विपरीत मिलेगा।
दीया

1
@AndyUK हैलो, ¿आप तुलना ऑपरेटर को लागू करने के लिए एक संरचना का उपयोग क्यों करते हैं? अग्रिम धन्यवाद
AER

C ++ में डिफ़ॉल्ट प्राथमिकता कतार एक अधिकतम प्राथमिकता कतार है।
qwr

30

priority_queueतुलनित्र के लिए तीसरा टेम्पलेट पैरामीटर है। इसका उपयोग करने के लिए सेट करें greater

जैसे

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

आप की आवश्यकता होगी #include <functional>के लिए std::greater


@Potatoswatter: हमेशा ऐसा नहीं होता है।
ऊंट

11
यह स्वीकार किए गए उत्तर से बेहतर है क्योंकि इसमें #include <कार्यात्मक>
reggaeguitar

22

आप इसे कई तरीकों से कर सकते हैं:
1. greaterतुलना फ़ंक्शन के रूप में उपयोग करना :

 #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. सकारात्मक संख्या के लिए उनके चिह्न (शून्य से -) का उपयोग करके और नकारात्मक संख्या के लिए प्लस (+) का उपयोग करके मूल्यों को सम्मिलित करना:

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. कस्टम संरचना या वर्ग का उपयोग करना:

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. कस्टम संरचना या वर्ग का उपयोग करके आप किसी भी क्रम में प्राथमिकता_का उपयोग कर सकते हैं। मान लीजिए, हम लोगों को उनके वेतन के अनुसार अवरोही क्रम में क्रमबद्ध करना चाहते हैं और यदि टाई है तो उनकी उम्र के अनुसार।

    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. ऑपरेटर ओवरलोडिंग द्वारा एक ही परिणाम प्राप्त किया जा सकता है:

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

    मुख्य समारोह में:

    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;
    }

क्या आपका मतलब bool operator > (const people & p)const 5 में नहीं है ) ऑपरेटर ओवरलोडिंग
रॉकस्टार

1
वास्तव में, आपका अधिकार, 5) काम करता है, यह सिर्फ अजीब है, मैंने कभी नहीं देखा है < तरह से अतिभारित है, यह बेहतर है अधिभार >और उपयोग करने के लिएgreater<people>
Rockstar5645

19

C ++ 11 में आप सुविधा के लिए एक उपनाम भी बना सकते हैं:

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

और इसे इस तरह से उपयोग करें:

min_heap<int> my_heap;

8

इस समस्या को हल करने का एक तरीका यह है कि प्राथमिकता में प्रत्येक तत्व के नकारात्मक को धकेल दें। इसलिए सबसे बड़ा तत्व सबसे छोटा तत्व बन जाएगा। पॉप ऑपरेशन करने के समय, प्रत्येक तत्व की उपेक्षा करें।

#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

उपरोक्त सभी उत्तरों के आधार पर मैंने प्राथमिकता कतार बनाने के लिए एक उदाहरण कोड बनाया। नोट: यह C ++ 11 और इसके बाद के संकलकों पर काम करता है

#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;
}

उपरोक्त कोड का आउटपुट

Enter number of elements N = 4

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

1

हम कई तरीकों का उपयोग करके ऐसा कर सकते हैं।

टेम्पलेट तुलनित्र पैरामीटर का उपयोग करना

    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;
    }

प्रयुक्त परिभाषित कम्पार्टर वर्ग का उपयोग करना

     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;
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.