二项队列 C++实现

来源:互联网 发布:2015年十大网络流行语 编辑:程序博客网 时间:2024/05/22 10:29
二项队列是比左式堆与斜堆更好的选择。

二项队列不是一棵树,是由堆序的集合组成的,成为森林。堆序中每一颗树都有约束,都为二项树,每一个高度只有一个二项树,每层的高度由两个下一层高度的树组成。B1= B0 + B0。
二项树

二项队列的合并是相同高度的二项树合并,并且insert与deleteMin都是依靠合并这个操作实现的。
insert
deleteMin

template<typename T>class BinomialQueue{public:    BinomialQueue();    BinomialQueue(const T &t);    BinomialQueue(const BinomialQueue &rhs);    ~BinomialQueue();    bool isEmpty() const;    const T & findMin() const;    void insert(const T &t);    void deleteMin();    void deleteMin(T & t);    void makeEmpty();    void merge(BinomialQueue & rhs);    const BinomialQueue & operator= (const BinomialQueue &rhs);private:    struct BinomialNode    {        T element;        BinomialNode * leftChild;        BinomialNode * nextSibling;        BinomialNode(const T & t, BinomialNode * lc, BinomialNode *ns) : element(t), leftChild(lc), nextSibling(ns) {}    };    enum { DEFAULT_TREES = 1};    int currentSize;    vector<BinomialNode *> theTrees;    int findMinIndex() const;    int capacity() const;    BinomialNode * combineTrees(BinomialNode * t1, BinomialNode * t2);    void makeEmpty(BinomialNode * & t);    BinomialNode * clone(BinomialNode * t) const;};template<typename T>BinomialNode * BinomialQueue<T>::combineTrees(BinomialNode * t1, BinomialNode * t2){    if (t2->element < t1->element)        return combineTrees(t2, t1);    t2->nextSibling = t1->leftChild;    t1->leftChild = t2;    return t1;}template<typename T>void BinomialQueue<T>::merge(BinomialQueue & rhs){    if (this == &rhs)        return;    currentSize == rhs.currentSize > theTrees.size() ? rhs.currentSize + 1 : theTrees.size() + 1;    //上一层树合并生成的下一层树,没有则为空    BinomialNode * carry = nullptr;    //书上写的这个j是什么意思啊? 求解    for (int i = 0, j = 1; i < currentSize; ++i, j *= 2)    {        BinomialNode * t1 = theTrees[i];        BinomialNode * t2 = i < rhs.theTrees.size() ? rhs.theTrees[i] : nullptr;        int whichCase = t1 == nullptr ? 0 : 1;        whichCase += t2 == nullptr ? 0 : 2;        whichCase += carry == nullptr ? 0 : 4;        switch (whichCase)        {        case 0://没有树        case 1://就有本身这棵树            break;        case 2://只有rhs有            theTrees[2] = t2;            rhs.theTrees[2] = nullptr;            break;        case 4://只有carry            theTrees[i] = carry;            carry = nullptr;            break;        case 3://有本身和rhs            carry = combineTrees(t1, t2);            theTrees[i] = rhs.theTrees[i] = nullptr;            break;        case 5://本身和carry            carry = combineTrees(t1, carry);            theTrees[i] = nullptr;            break;        case 6://rhs与carry            carry = combineTrees(t2, carry);            rhs.theTrees[i] = nullptr;            break;        case 7://本身、rhs、carry都有            theTrees[i] = carry;            carry = combineTrees(t1, t2);            rhs.theTrees[i] = nullptr;            break;        }    }    for (int k = 0; k < rhs.theTrees.size(); ++k)        rhs.theTrees[k] = nullptr;    rhs.currentSize = 0;}
0 0
原创粉丝点击