Initial commit
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
LeftistHeap.cpp - Implementation for leftist heap
|
||||
|
||||
#include "LeftistHeap.h"
|
||||
#include "dsexceptions.h"
|
||||
|
||||
/**
|
||||
* Construct the leftist heap.
|
||||
*/
|
||||
template <class Comparable>
|
||||
LeftistHeap<Comparable>::LeftistHeap( )
|
||||
{
|
||||
root = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
template <class Comparable>
|
||||
LeftistHeap<Comparable>::LeftistHeap( const LeftistHeap<Comparable> & rhs )
|
||||
{
|
||||
root = NULL;
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destruct the leftist heap.
|
||||
*/
|
||||
template <class Comparable>
|
||||
LeftistHeap<Comparable>::~LeftistHeap( )
|
||||
{
|
||||
makeEmpty( );
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge rhs into the priority queue.
|
||||
* rhs becomes empty. rhs must be different from this.
|
||||
*/
|
||||
template <class Comparable>
|
||||
void LeftistHeap<Comparable>::merge( LeftistHeap & rhs )
|
||||
{
|
||||
if( this == &rhs ) // Avoid aliasing problems
|
||||
return;
|
||||
|
||||
root = merge( root, rhs.root );
|
||||
rhs.root = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to merge two roots.
|
||||
* Deals with deviant cases and calls recursive merge1.
|
||||
*/
|
||||
template <class Comparable>
|
||||
LeftistNode<Comparable> *
|
||||
LeftistHeap<Comparable>::merge( LeftistNode<Comparable> * h1,
|
||||
LeftistNode<Comparable> * h2 ) const
|
||||
{
|
||||
if( h1 == NULL )
|
||||
return h2;
|
||||
if( h2 == NULL )
|
||||
return h1;
|
||||
if( h1->element < h2->element )
|
||||
return merge1( h1, h2 );
|
||||
else
|
||||
return merge1( h2, h1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to merge two roots.
|
||||
* Assumes trees are not empty, and h1's root contains smallest item.
|
||||
*/
|
||||
template <class Comparable>
|
||||
LeftistNode<Comparable> *
|
||||
LeftistHeap<Comparable>::merge1( LeftistNode<Comparable> * h1,
|
||||
LeftistNode<Comparable> * h2 ) const
|
||||
{
|
||||
if( h1->left == NULL ) // Single node
|
||||
h1->left = h2; // Other fields in h1 already accurate
|
||||
else
|
||||
{
|
||||
h1->right = merge( h1->right, h2 );
|
||||
if( h1->left->npl < h1->right->npl )
|
||||
swapChildren( h1 );
|
||||
h1->npl = h1->right->npl + 1;
|
||||
}
|
||||
return h1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps t's two children.
|
||||
*/
|
||||
template <class Comparable>
|
||||
void LeftistHeap<Comparable>::swapChildren( LeftistNode<Comparable> * t ) const
|
||||
{
|
||||
LeftistNode<Comparable> *tmp = t->left;
|
||||
t->left = t->right;
|
||||
t->right = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert item x into the priority queue, maintaining heap order.
|
||||
*/
|
||||
template <class Comparable>
|
||||
void LeftistHeap<Comparable>::insert( const Comparable & x )
|
||||
{
|
||||
root = merge( new LeftistNode<Comparable>( x ), root );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the smallest item in the priority queue.
|
||||
* Return the smallest item, or throw Underflow if empty.
|
||||
*/
|
||||
template <class Comparable>
|
||||
const Comparable & LeftistHeap<Comparable>::findMin( ) const
|
||||
{
|
||||
if( isEmpty( ) )
|
||||
throw Underflow( );
|
||||
return root->element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the smallest item from the priority queue.
|
||||
* Throws Underflow if empty.
|
||||
*/
|
||||
template <class Comparable>
|
||||
void LeftistHeap<Comparable>::deleteMin( )
|
||||
{
|
||||
if( isEmpty( ) )
|
||||
throw Underflow( );
|
||||
|
||||
LeftistNode<Comparable> *oldRoot = root;
|
||||
root = merge( root->left, root->right );
|
||||
delete oldRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the smallest item from the priority queue.
|
||||
* Pass back the smallest item, or throw Underflow if empty.
|
||||
*/
|
||||
template <class Comparable>
|
||||
void LeftistHeap<Comparable>::deleteMin( Comparable & minItem )
|
||||
{
|
||||
minItem = findMin( );
|
||||
deleteMin( );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the priority queue is logically empty.
|
||||
* Returns true if empty, false otherwise.
|
||||
*/
|
||||
template <class Comparable>
|
||||
bool LeftistHeap<Comparable>::isEmpty( ) const
|
||||
{
|
||||
return root == NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the priority queue is logically full.
|
||||
* Returns false in this implementation.
|
||||
*/
|
||||
template <class Comparable>
|
||||
bool LeftistHeap<Comparable>::isFull( ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the priority queue logically empty.
|
||||
*/
|
||||
template <class Comparable>
|
||||
void LeftistHeap<Comparable>::makeEmpty( )
|
||||
{
|
||||
reclaimMemory( root );
|
||||
root = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deep copy.
|
||||
*/
|
||||
template <class Comparable>
|
||||
const LeftistHeap<Comparable> &
|
||||
LeftistHeap<Comparable>::
|
||||
operator=( const LeftistHeap<Comparable> & rhs )
|
||||
{
|
||||
if( this != &rhs )
|
||||
{
|
||||
makeEmpty( );
|
||||
root = clone( rhs.root );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to make the tree empty.
|
||||
* WARNING: This is prone to running out of stack space;
|
||||
* exercises suggest a solution.
|
||||
*/
|
||||
template <class Comparable>
|
||||
void LeftistHeap<Comparable>::reclaimMemory( LeftistNode<Comparable> * t ) const
|
||||
{
|
||||
if( t != NULL )
|
||||
{
|
||||
reclaimMemory( t->left );
|
||||
reclaimMemory( t->right );
|
||||
delete t;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to clone subtree.
|
||||
* WARNING: This is prone to running out of stack space.
|
||||
* exercises suggest a solution.
|
||||
*/
|
||||
template <class Comparable>
|
||||
LeftistNode<Comparable> *
|
||||
LeftistHeap<Comparable>::clone( LeftistNode<Comparable> * t ) const
|
||||
{
|
||||
if( t == NULL )
|
||||
return NULL;
|
||||
else
|
||||
return new LeftistNode<Comparable>( t->element, clone( t->left ),
|
||||
clone( t->right ), t->npl );
|
||||
}
|
||||
Reference in New Issue
Block a user