头文件:
/*****************************************************************************
* binaryheap.h
*
* Minimum binary heap implemented by C++ template class.
*
* This class provides the following operatins of a minimum binary heap:
* build a heap
* insert an element into the heap
* find the minimum element in the heap
* delete the minimum element in the heap
*
* The defualt initial size of the heap is set to 20. If the elements number
* exceed initial size, then it will be extended by a factor of 2.
*
* Zhang Ming, 2009-10
*****************************************************************************/
#ifndef BINARYHEAP_H
#define BINARYHEAP_H
#include <iostream>
#include <cstdlib>
#include <constants.h>
using namespace std;
namespace itlab
{
template <typename Type>
class BinaryHeap
{
public:
explicit BinaryHeap( int maxSize = INITSIZE );
BinaryHeap( Type *array, int length );
~BinaryHeap();
// BinaryHeap( const BinaryHeap<Type> &rhs );
// BinaryHeap<Type>& operator=( const BinaryHeap<Type> &rhs );
inline bool isEmpty() const;
inline void makeEmpty();
inline void insert( const Type &x );
inline void findMin( Type &x );
inline void deleteMin();
inline void deleteMin( Type &minItem );
private:
Type *elements;
int currentSize;
int capacity;
void filterDown( int hole );
void filterUp( int hole );
void handleOverflow();
inline void handleUnderflow();
};
// class BinaryHeap
#include <binaryheap-impl.h>
}
// namespace itlab
#endif
// BINARYHEAP_H
实现文件:
/*****************************************************************************
* binaryheap-impl.h
*
* Implementation for BinaryHeap class.
*
* Zhang Ming, 2009-10
*****************************************************************************/
/**
* constructors and destructor
*/
template <typename Type>
BinaryHeap<Type>::BinaryHeap( int maxSize )
{
capacity = maxSize;
elements = new Type[capacity+1];
if( elements == NULL )
cerr << "Out of memory!" << endl;
currentSize = 0;
}
template <typename Type>
BinaryHeap<Type>::BinaryHeap( Type *array, int length )
{
capacity = ( INITSIZE > length ) ? INITSIZE : length;
elements = new Type[capacity+1];
if( elements == NULL )
cerr << "Out of memory!" << endl;
for( int i=0; i<length; ++i )
elements[i+1] = array[i];
currentSize = length;
for( int i=currentSize/2; i>0; --i )
filterDown( i );
}
template <typename Type>
BinaryHeap<Type>::~BinaryHeap()
{
currentSize = 0;
capacity = INITSIZE;
delete []elements;
}
/**
* If the heap is empty, return true.
*/
template <typename Type>
inline bool BinaryHeap<Type>::isEmpty() const
{
return currentSize == 0;
}
/**
* Make the heap empty.
*/
template <typename Type>
inline void BinaryHeap<Type>::makeEmpty()
{
currentSize = 0;
}
/**
* Insert item x, allowing duplicates.
*/
template <typename Type>
inline void BinaryHeap<Type>::insert( const Type &x )
{
if( currentSize == capacity )
handleOverflow();
elements[++currentSize] = x;
filterUp( currentSize );
}
/**
* Find the smallest item in the heap.
*/
template <typename Type>
inline void BinaryHeap<Type>::findMin( Type &x )
{
if( !isEmpty() )
x = elements[1];
else
handleUnderflow();
}
/**
* Remove the minimum item.
*/
template <typename Type>
inline void BinaryHeap<Type>::deleteMin()
{
if( !isEmpty() )
{
elements[1] = elements[currentSize--];
filterDown( 1 );
}
else
handleUnderflow();
}
/**
* Remove the minimum item and place it in minItem.
*/
template <typename Type>
inline void BinaryHeap<Type>::deleteMin( Type &minItem )
{
if( !isEmpty() )
{
minItem = elements[1];
elements[1] = elements[currentSize--];
filterDown( 1 );
}
else
handleUnderflow();
}
/**
* Percolate down the heap, begin at "hole".
*/
template <typename Type>
void BinaryHeap<Type>::filterDown( int hole )
{
int child;
Type tmp = elements[hole];
for( ; 2*hole<=currentSize; hole=child )
{
child = 2*hole;
if( child != currentSize && elements[child+1] < elements[child] )
child++;
if( elements[child] < tmp )
elements[hole] = elements[child];
else
break;
}
elements[hole] = tmp;
}
/**
* Percolate up the heap, begin at "hole".
*/
template <typename Type>
void BinaryHeap<Type>::filterUp( int hole )
{
Type tmp = elements[hole];
for( ; hole>1 && tmp<elements[hole/2]; hole/=2 )
elements[hole] = elements[hole/2];
elements[hole] = tmp;
}
/**
* If the capability of the heap exceeds the initial size, make it double.
*/
template <typename Type>
void BinaryHeap<Type>::handleOverflow()
{
capacity = EXTFACTOR * capacity;
Type *newArray = new Type[capacity+1];
if( newArray == NULL )
{
cerr << "Out of memory!" << endl;
exit(1);
}
for( int i=1; i<=currentSize; ++i )
newArray[i] = elements[i];
delete []elements;
elements = newArray;
};
/**
* Handle the error of get element from an empty heap.
*/
template <typename Type>
inline void BinaryHeap<Type>::handleUnderflow()
{
cerr << "The heap is empty!" << endl << endl;
exit( 1 );
};
测试文件:
/*****************************************************************************
* heap_test.cpp
*
* Minimum binary heap class testing.
*
* Zhang Ming, 2009-10
*****************************************************************************/
#include <iostream>
#include <random.h>
#include <binaryheap.h>
using namespace std;
using namespace itlab;
int main()
{
int x, a[100];
Random r(1);
BinaryHeap<int> h;
for( int i=1; i<=25; ++i )
h.insert( r.random( 1, 100 ) );
while( !h.isEmpty() )
{
h.findMin( x );
cout << " " << x << "\t";
h.deleteMin();
}
cout << endl;
cout << endl << endl;
for( int i=0; i<40; ++i )
{
a[i] = r.random( 1, 100 );
cout << " " << a[i] << "\t";
}
cout << endl;
BinaryHeap<int> hh( a, 40 );
while( !hh.isEmpty() )
{
hh.deleteMin( x );
cout << " " << x << "\t";
}
cout << endl;
for( int i=1; i<=5; ++i )
h.insert( r.random( 1, 100 ) );
h.makeEmpty();
h.deleteMin();
cout << endl << endl;
return 0;
}