左式堆

左式堆核心是合并操作。增加了新的数据成员,零路径长(npl)。左儿子的npl不小于右儿子,父节点的npl等于右儿子npl加1。在合并操作中要保持左式堆的性质并更新节点的npl。合并的方式为递归的将具有较大根值的堆与具有较小根植的堆的右子树合并。

template <typename Comparable>
class LeftistHeap
{
public:
    LeftistHeap();
    LeftistHeap(const LeftistHeap & rhs);
    LeftistHeap(LeftistHeap && rhs);

    ~LeftistHeap()
    {
        makeEmpty();
    }

    LeftistHeap & operator=(const LeftistHeap & rhs);
    LeftistHeap & operator=(LeftistHeap && rhs);

    bool isEmpty()const;
    const Comparable & findMin()const;

    void insert(const Comparable & x);
    void insert(Comparable && x);
    void deleteMin();
    void deleteMin(Comparable & minItem);
    void makeEmpty();
    void merge(LeftistHeap & rhs);

private:
    struct LeftistNode
    {
        Comparable  element;
        LeftistNode *left;
        LeftistNode *right;
        int         npl;

        LeftistNode(const Comparable & e,LeftistNode *lt=nullptr,
                    LeftistNode * rt=nullptr,int np=0)
        :element(e),left(lt),right(rt),npl(np){}

        LeftistNode(Comparable && e,LeftistNode * lt=nullptr,
                    LeftistNode * rt=nullptr ,int np=0)
        :element(e),left(lt),right(rt),npl(np){}


    };

    LeftistNode * root;

    LeftistNode * merge(LeftistNode *h1,LeftistNode *h2);
    LeftistNode * merge1(LeftistNode *h1,LeftistNode *h2);

    void swapChildren(LeftistNode * t);
    void reclaimMemeory(LeftistNode * t);
    LeftistNode * clone(LeftistNode * t)const;
};

template <typename Comparable>
void LeftistHeap<Comparable>::merge(LeftistHeap & rhs)
{
    if(this==&rhs)
        return;

    root=merge(root,rhs.root);
    rhs.root=nullptr;
}

template <typename Comparable>
typename LeftistHeap<Comparable>::LeftistNode * LeftistHeap<Comparable>::
merge(LeftistNode *h1,LeftistNode *h2)
{
    if(h1==nullptr)
        return h2;
    if(h2==nullptr)
        return h1;
    if(h1->element<h2->element)
        return merge1(h1, h2);
    else
        return merge1(h2, h1);
}

template <typename Comparable>
typename LeftistHeap<Comparable>::LeftistNode * LeftistHeap<Comparable>::
merge1(LeftistNode *h1, LeftistNode *h2)
{
    if(h1->left==nullptr)
        h1->left=h2;
    else
    {
        h1->right=merge(h1->right,h2);      //合并操作,较小值的右节点与较大值合并
        if(h1->left->npl<h1->right->npl)    //维持左式堆特性,左npl不小于右npl
            swapChildren(h1);
        h1->npl=h1->right->npl+1;           //更新npl

    }
    return h1;
}

template <typename Comparable>
void LeftistHeap<Comparable>::insert(const Comparable &x)
{
    root=merge(new LeftistNode{x},root);
}

template <typename Comparable>
void LeftistHeap<Comparable>::deleteMin()
{
    //if(isEmpty())
      //  throw UnderflowException{};
    LeftistNode *oldRoot=root;
    root=merge(root->left,root->right);
    delete oldRoot;
}

template <typename Comparable>
void LeftistHeap<Comparable>::deleteMin(Comparable &minItem)
{
    minItem=findMin();
    deleteMin();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值