左式堆核心是合并操作。增加了新的数据成员,零路径长(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();
}