7

二分木に対するヒープの唯一の利点は、二分木のO(log(2)n)ではなく、O(1)の複雑さでヒープ内の最小のアイテムを見つけることであるように思われます。

優先キューを実装するときは、データ構造からそれぞれ最小のアイテムを削除する必要があります。ツリーから最小のアイテムを削除し、両方のヒープをO(log(2)n)の複雑さで実行します。ツリーからアイテムを削除することは、より複雑な場合があります。子のないアイテムの削除は、実際には非常に簡単です。

私の質問は、優先キューを実装するときに、なぜバイナリツリー(この場合はより単純です)の代わりにヒープを使用するのですか?

4

5 に答える 5

11

二分木の場合の最悪の場合の複雑さは、二分木がヒープ内にある間に配列に収束するときにO(n)になり、O(log(n))のままになります。赤黒やAV1のようなバランスの取れた二分木を使用できますが、そうすると、より複雑になり、より多くのメモリが必要になります。

于 2013-03-26T19:46:31.803 に答える
5

ヒープは通常、適切にバランスの取れた二分木よりも実装が簡単です。さらに、必要なメモリオーバーヘッドが少なく(要素はツリーノードやポインタなどすべてを割り当てることなく配列に直接格納できます)、パフォーマンスが向上する可能性があります(主に単一の連続した配列を使用するメモリの局所性による)...なぜ使ってみませんか?

于 2013-03-26T19:58:42.110 に答える
5

最初の選択は、予想されるアクセスパターンと、保存する可能性のあるデータの量によって異なります。...

  • データがそれほど多くない場合(たとえば、30未満)、ソートされていない配列で問題ありません。
  • 追加、削除、または更新することがほとんどない場合は、ソートされた配列で問題ありません。
  • nがたとえば100万未満で、最上位の要素(最初または最後にランク付けされた要素)のみを検索している場合、ヒープは適切に機能します(特に、ランダムに選択された要素を頻繁に更新する場合は、たとえば、キャッシュのLRU(最近使用されていない)キューで実行します。これは、平均して、このような更新がO(log(n))ではなくO(1)であるためです。
  • nがたとえば100万未満で、何を検索するかわからない場合は、バランスの取れたツリー(たとえば、赤黒またはAVL)で問題ありません。
  • nが大きい場合(たとえば、100万以上)、bツリーまたはトライを使用したほうがよいでしょう(nが十分に大きくなると、バランスの取れた二分木のパフォーマンスは「崖から落ちる」傾向があります。メモリアクセス散らばりすぎる傾向があり、キャッシュミスは本当に傷つき始めます)

...ただし、オプションをできるだけ開いたままにして、少なくとも1つの選択肢のベンチマークを行い、パフォーマンスが向上した場合はそれに切り替えることができるようにすることをお勧めします。

過去20年間、私はヒープが何にでも最適な2つのアプリケーションにのみ取り組んできました(1回はLRUで、もう1回は厄介なオペレーションズリサーチアプリケーションで、ランダムに摂動されたk次元超立方体への加法性を復元します。ハイパーキューブ内のセルはk個の異なるヒープに表示され、メモリは貴重でした)。ただし、これら2つの場合、それらは代替案よりもはるかに優れたパフォーマンスを示しました。バランスの取れたツリーやbツリーよりも文字通り数十倍高速です。

前の段落で述べたハイパーキューブの問題について、私のチームリーダーは、赤黒木はヒープよりもパフォーマンスが優れていると考えていましたが、ベンチマークでは、赤黒木ははるかに遅いことが示されました(覚えているように、約20倍遅い) )、そしてb-treeはかなり高速でしたが、ヒープもそれらを快適に打ち負かしました。

ヒープの重要な機能は、上記の両方の場合で、最小値のO(1)ルックアップではなく、ランダムに選択された要素のO(1)平均更新時間でした。

-James Barbetti(まあ、私はそうだと思っていました。しかし、キャプチャは私が人間ではないと言い続けています)

于 2013-04-22T11:18:46.107 に答える
0

まず第一に、さまざまな二分木があり(それらのいくつかは非常に困難であり、それらのいくつかは平均しか提供しませんO(log n))、ヒープはそれらの1つです。

2つ目:ほとんどのツリーでの操作はO(log n)複雑ですが、より複雑であり、一定の要因があります。

ヒープには一定の追加メモリが必要ですが、ツリーは通常、すべてのノードにポインタを格納する必要があります。

ちなみに、ヒープは非常に簡単で、配列のみを使用します(Javaでこのように実装されているかどうかはわかりませんが、そう思います)

于 2013-03-26T19:40:07.537 に答える
0

検索または検索操作を頻繁に使用する場合は、平衡二分木が推奨されます。線分交差コードは、この1つの理由により、ヒープではなくバランスの取れたツリーを使用します。

于 2013-07-25T05:53:13.447 に答える