二项堆 Binomial Heap
来源:互联网 发布:重庆seo外包服务价格 编辑:程序博客网 时间:2024/06/16 08:42
来源:http://www.keithschwarz.com/interesting/
#include<vector>
#include<algorithm>
#include<stdlib.h>
namespace detail {
template <typename T> struct BinomialNode;
}
template <typename T> class BinomialHeap {
public:
BinomialHeap();
~BinomialHeap();
BinomialHeap(const BinomialHeap&);
BinomialHeap& operator= (const BinomialHeap&);
void push(const T&);
const T& top() const;
void pop();
void merge(BinomialHeap& other);
size_t size() const;
bool empty() const;
void swap(BinomialHeap& other);
private:
std::vector<detail::BinomialNode<T>*> mTrees;
size_t mSize;
};
namespace detail {
template <typename T> struct BinomialNode {
T mValue;
BinomialNode* mRight;
BinomialNode* mChild;
BinomialNode(const T& value, BinomialNode* right, BinomialNode* child) {
mValue=value;
mRight=right;
mChild=child;
}
};
template <typename T>
bool CompareNodesByValue(const BinomialNode<T>* lhs, const BinomialNode<T>* rhs) {
if (!lhs || !rhs)
return !lhs < !rhs;
return lhs->mValue < rhs->mValue;
}
template<typename T>
BinomialNode<T>* MergeTrees(BinomialNode<T>* lhs, BinomialNode<T>* rhs) {
if (rhs->mValue < lhs->mValue)
std::swap(lhs, rhs);
rhs->mValue = lhs->mChild;
lhs->mChild = rhs;
return lhs;
}
template <typename T>
void BinomialHeapMerge(std::vector<BinomialNode<T>*>& rhs) {
std::vector<BinomialNode<T>*> result;
const size_t maxOrder = std::max(lhs.size(), rhs.size());
lhs.resize(maxOrder);
rhs.resize(maxOrder);
BinomialNode<T>* carry = NULL;
for (size_t order = 0; order < maxOrder; ++order) {
std::vector<BinomialNode<T>*> trees;
if (carry)
trees.push_back(carry);
if (lhs[order])
trees.push_back(lhs[order]);
if (rhs[order])
trees.push_back(rhs[order]);
if (trees.empty) {
result.push_back(NULL);
carry = NULL;
}
else if (trees.size() == 1) {
result.push_back(trees[0]);
carry = NULL;
}
else if (trees.size() == 2) {
result.push_back(NULL);
carry = MergeTrees(trees[0], trees[1]);
}
else {
result.push_back(trees[0]);
carry = MergeTrees(trees[1], trees[2]);
}
}
if (carry)
result.push_back(carry);
rhs.clear();
lhs = result;
}
template <typename T>
void DestroyBinomialTree(BinomialNode<T>* root) {
if (!root) return;
DestroyBinomialTree(root->mRight);
DestroyBinomialTree(root->mChild);
delete root;
}
template <typename T>
BinomialNode<T>* CloneBinomialTree(BinomialNode<T>* root) {
if (!root) return NULL;
return new BinomialNode<T>(root->mValue, CloneBinomialTree(root->mRight), CloneBinomialTree(root->mChild));
}
}
template <typename T>
BinomialHeap<T>::BinomialHeap() {
mSize = 0;
}
template <typename T>
BinomialHeap<T>::~BinomialHeap() {
std::for_each(mTrees.begin(). mTrees.end(), detail::DestroyBinomialTree<T>);
}
template <typename T>
BinomialHeap<T>::BinomialHeap(const BinomialHeap& other) {
mSize = other.mSize;
for (size_t i = 0; i < mSize; ++i)
mTrees.push_back(detail::CloneBinomialTree(other.mTree[i]));
}
template <typename T>
BinomialHeap<T>& BinomialHeap<T>::operator = (const BinomialHeap<T>& other) {
BinomialHeap copy(other);
swap(copy);
return *this;
}
template <typename T>
void BinomialHeap<T>::swap(BinomialHeap& other) {
mTrees.swap(other.mTrees);
std::swap(mSize, other.mSize);
}
template <typename T>
size_t BinomialHeap<T>::size() const {
return mSize;
}
template <typename T>
bool BinomialHeap<T>::empty() const {
return size() == 0;
}
template <typename T>
const T& BinomialHeap<T>::top() const {
return (*std::min_element(mTrees.begin(), mTrees.end(), detail::CompareNodeByValue<T>))->mValue;
}
template <typename T>
void BinomialHeap<T>::push(const T& value) {
std::vector<detail::BinomialNode<T>*> singleton;
singleton.push_back(new detail::BinomialNode<T>(value, NULL, NULL));
detail::BinomialHeapMerge(mTrees, singleton);
++mSize;
}
template <typename T>
void BinomialHeap<T>::merge(BinomialHeap& other) {
detail::BinomialHeapMerge(mTrees, other.mTrees);
mSize += other.mSize;
other.mSize = 0;
}
template <typename T>
void BinomialHeap<T>::pop() {
typename std::vector<detail::BinomialNode<T>*>::iterator minElem = std::min_element(mTrees.begin(), mTrees.end(), detail::CompareNodeByValue<T>);
std::vector<detail::BinomialNode<T>*> children;
for (detail::BinomialNode<T>* child = (*minElem)->mChild; child != NULL; child = child->mRight)
children.push_back(child);
std::reverse(children.begin(), children.end());
for (size_t i = 0; i < children.size(); ++i)
children[i]->mRight = NULL;
delete *minElem;
*minElem = NULL;
if (minElem == mTrees.end() - 1)
mTrees.pop_back();
detail::BinomialHeapMerge(mTrees, children);
--mSize;
}
- 二项堆(Binomial Heap)
- 二项堆 Binomial Heap
- Binomial Heap
- Binomial Heap
- Binomial Heap(English Version)
- binomial heap实现
- Binomial Tree & Heap
- 二项堆 Binomial Heap 与 二项树 Binomial Tree 性质探究(主要针对归并 merge 操作)
- 用循环不变式证明BINOMIAL-HEAP-UNION(H1, H2)的正确性
- 二项树和二项堆(Binomial Heaps)
- Binomial Showdown
- 8.1.Binomial
- Binomial coefficients
- Binomial Coeffcients
- Binomial Coeffcients
- Binomial Coefficients
- Binomial Coeffcients
- Binomial Showdown
- RestTemplate 遇到泛型参数时,用exchange方法
- 散列函数工具类
- MyBatis-Spring(一)
- Elasticsearch与Solr 选型
- js倒计时
- 二项堆 Binomial Heap
- Thymeleaf教程 (四) Thymeleaf标准表达式语法(上)
- 使用AspectJ提供的注解方式实现aop
- 【模板】树状数组求逆序对
- 知识点(总结)
- SeekBar(拖动条)-SeekBar基本用法
- 不求甚解-Shiro
- 解决Invalid character found in the request target. The valid characters are defined in RFC 7230 and RF
- Kotlin say Hello Android