web-dev-qa-db-ja.com

stlで最小ヒープを維持する簡単な方法は?

ユーザー定義の構造体の場合、私が理解しているように、それは簡単です。演算子<をオーバーロードするだけです。しかし、int/floatなどの場合、intの演算子<を本当にオーバーロードする必要がありますか?これが私が試したものです:

       #include <iostream>
       #include <algorithm>
       #include <vector>
       using namespace std;

       bool comp(const int& a, const int& b)
       {
          return a<b?false:true;
       }

       int main () 
       {
         int myints[] = {10,20,30,5,15};
         vector<int> v(myints,myints+5);
         vector<int>::iterator it;
         make_heap(v.begin(), v.end(), comp);
         cout << "initial min heap   : " << v.front() << endl;
         for (unsigned i=0; i<v.size(); i++) cout << " " << v[i];
         cout<<endl;

         pop_heap (v.begin(),v.end());
         v.pop_back();
         for (unsigned i=0; i<v.size(); i++) cout << " " << v[i];
         cout<<endl;
       }

結果は次のとおりです。

        initial min heap   : 5
        5 10 30 20 15
        30 10 15 20

pop_heapになりましたが、Push_heapは最小ヒープを正しく維持しませんか?これを達成するためのより簡単な方法はありますか?ありがとう!

編集:申し訳ありませんが、私はマニュアルを注意深くチェックしませんでした。はい、compをpop_heapまたはPush_heapに渡すとうまくいくはずです。しかし、どういう意味ですか、外部コンパレータを使用するべきではありませんか?それが正しい方法ではない場合、これを達成するための一般的な方法は何ですか?

19
user268451

intに対してoperator <をオーバーロードする必要はありません(実際にはオーバーロードできません)。外部コンパレータを使用する場合は、同じComparator comppop_headにも渡す必要があります。

*編集:*

Ildjarnが指摘したように、比較演算子は厳密な弱順序関係を実装していません。

a < b ? false : true; --> a >= b
b < a ? true : false; --> a > b
8
K-ballo

std::greater<int>()をコンパレータとして使用します(すべてのmake_heapPush_heappop_heap)。 () 重要です - std::greater<int>は関数ではなくファンクタークラスであるため、そのインスタンスが必要です。

29
Steve Jessop

答えは良いので、ちょっとした例を付け加えたいと思いました。次の配列があるとします。

array<int, 10> A{5,2,8,3,4,1,9,12,0,7};

min heapを作成したいとします。これを行う最も簡単な方法は、make_heapアルゴリズムを使用することです。ただし、デフォルトではmax heapが作成されます。言い換えれば、あなたが呼び出す場合:

make_heap(A.begin(), A.end());

Amax heapになります。一方、min heapを使用するには、コンパレータを追加する必要がありますが、コンパレータを実装する必要はありません。代わりに、次のようにメソッドを呼び出します。

make_heap(A.begin(), A.end(), greater<int>());

この呼び出しにより、配列がmin heapになります。

PS:#include <algorithm>を使用するにはstd::make_heapが必要です。同じ操作がvectorにも適用されます。

HTH!

16
erol yeniaras