The class will include an Insert method so new values can be added to the heap. This presents a problem. If we put a limit on the size of the heap (i.e. by using a declaration such as int heap_array[ 100 ];), the insert will eventually fail. Of course, we can dynamically allocate the heap based on some initial size. Once the heap reaches that size and an insert is attempted, we can then simply allocate a new heap that is larger and copy the contents from the original heap. How much larger should the new heap be, though?
If we allocate a new heap that can hold only 1 more value, then the next time an insert is done, another new heap will need to be allocated. This will continue to be the case for every insert (unless values are also removed), which is very inefficient. However, if we allocate a heap that can hold double the number of current values, we might end up wasting a lot of memory if only a few more inserts are performed.
There is no easy solution to this problem, so our class will shift the responsibility to whoever uses the class. When a new Heap is created, an increment value will be included. Whenever the heap is full and needs to be reallocated, its size is increased by this value.
What kind of errors can occur? Dynamically allocating the heap might fail or there might be an underflow. In either case, our class will throw an exception. See the section on Handing Exceptions for details.
The first constructor is passed 2 integer arguments, an initial size and an increment size. Both of these arguments should be checked to make sure they are larger than 0. If either arguments is 0 or less, an exception should be thrown. (See below for details on this.) The array_size and inc_size variables should be set to these argument values. This constructor should then allocate a new heap_array based on the initial size. If this allocation fails, an exception should be thrown. Because this array is initially empty, the heap_size variable should be set to 0.
The second constructor is passed an array of integers and 2 integer arguments; the size of the array and an increment size. If the array is NULL or either of the other arguments is 0 or less, an exception should be thrown. A new heap_array should be allocated based on the size of the passed array, the contents of the passed array should be copied to the heap_array, then the BuildHeap() method should be called (to make the heap_array into an actual heap). If allocating the heap_array fails, an exception should be thrown. The array_size and heap_size variables should both be set to the size of the passed array. The inc_size variable should be set to the increment size.
Note that this method does not need to perform any error checking (i.e. a check to see if the array is NULL or the index is invalid). Why?
This method should check that the heap array is not NULL and, if a new heap array needs to be allocated, that the allocation succeeded. If either of these are not true, an exception should be thrown.
throw exception();
In your main() program, when you call Heap functions, you must enclose
these calls in try...catch blocks in order to catch any exceptions thrown.
For example:
Heap *heap = NULL;
try
{
heap = new Heap( 10, 5 );
}
catch( exception e )
{
cout << "Creating the heap failed!\n";
return 0;
}
It is easier to understand exceptions by seeing them in action. I have written a short program that demonstrates them. Click here to see it. I recommend you download, compile, and run this program to better understand what it is doing.