6

ペアリング ヒープ データ構造を実装しました。ペアリング ヒープは、O(1) 償却時間で挿入、検索分、マージをサポートし、O(logN) 償却時間で削除、削除分をサポートします。しかし、最も顕著な操作は、複雑さ O(log logN) を持つ減少キーです。ペアリング ヒープの詳細については、http://en.wikipedia.org/wiki/Pairing_heapを参照してください。

insert、merge、および delete-min 操作を実装しましたが、ウィキペディアの記事には特定のノードのキーを減らす方法が記載されていなかったため、実装できませんでした。誰かが実際にどのように機能するか教えてもらえますか?

これが私のコードです:

template< class key_t, class compare_t=std::less< key_t > >
struct pairing_heap {
private:
  struct node { 
    key_t key; std::vector< node* > c;
    node( key_t k=key_t() ) : key( k ), c( std::vector< node* >() ) {}
  };
  node *root;
  compare_t cmp;
  unsigned sz;
public:
  typedef key_t value_type;
  typedef compare_t compare_type;
  typedef pairing_heap< key_t, compare_t > self_type;

  pairing_heap() : root( 0 ) {}
  node* merge( node *x, node *y ) {
    if( !x ) return y;
    else if( !y ) return x;
    else {
      if( cmp( x->key, y->key ) ) {
        x->c.push_back( y );
        return x;
      } else {
        y->c.push_back( x );
        return y;
      }
    }
  }
  node* merge_pairs( std::vector< node* > &c, unsigned i ) {
    if( c.size()==0 || i>=c.size() ) return 0;
    else if( i==c.size()-1 ) return c[ i ];
    else {
      return merge( merge( c[ i ], c[ i+1 ] ), merge_pairs( c, i+2 ) );
    }
  }
  void insert( key_t x ) {
    root = merge( root, new node( x ) );
    sz++;
  }
  key_t delmin() {
    if( !root ) throw std::runtime_error( "std::runtime_error" );
    key_t ret=root->key;
    root = merge_pairs( root->c, 0 );
    sz--;
    return ret;
  }
  bool empty() const { return root==0; }
  unsigned size() const { return sz; }
};
4

1 に答える 1

6

ペアリング ヒープに関する元の論文の 114 ページによると、キーの減少操作は次のように実装されます。まず、キーを下げるノードの優先度を新しい優先度に変更します。その優先度がまだ親よりも大きい場合 (またはツリーのルートである場合)、作業は完了です。それ以外の場合は、そのノードからその親へのリンクを切断してから、マージ操作を使用して、元のヒープをそのツリーから切断されたばかりのサブツリーと結合します。

お役に立てれば!

于 2012-12-18T19:44:53.640 に答える