配对堆 - 减少键的实现
Pairing heap - implementation of decrease key
本文关键字:实现 更新时间:2023-10-16
我刚刚实现了配对堆数据结构。配对堆支持插入、查找分钟、合并 O(1) 摊销时间和 O(logN) 摊销时间中的删除、删除分钟。但最显着的操作是 reduce 键,它具有复杂性 O(log logN)。有关配对堆的更多信息,请参阅 http://en.wikipedia.org/wiki/Pairing_heap。
我已经实现了插入、合并和删除分钟操作,但维基百科文章没有说明如何减少给定节点的键,所以我无法实现它。有人可以告诉我它实际上是如何工作的吗?
这是我的代码:
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; }
};
根据关于配对堆的原始论文,第 114 页,减少键操作实现如下。 首先,将要降低其键的节点的优先级更改为具有新优先级。 如果它的优先级仍然大于它的父级(或者如果它是树的根),你就完成了。 否则,切断从该节点到其父节点的链接,然后使用合并操作将原始堆与刚刚从该树上剪切的子树合并。
希望这有帮助!
相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- std::random_device是如何实现的