#ifndef ARRAY_MAX_HEAP_
#define ARRAY_MAX_HEAP_
#include "HeapInterface.h"
#include "PrecondViolatedExcept.h"
#include <math.h>
#include <stdio.h>
template<class ItemType>
class ArrayMaxHeap : public HeapInterface<ItemType>
{
private:
staticconstint ROOT_INDEX = 0; // Helps with readibility
staticconstint DEFAULT_CAPACITY = 21;
ItemType* items; // Array of heap items
int itemCount; // Current count of heap items
int maxItems; // Max capcity of the heap
// Returns the array index of the left child
int getLeftChildIndex(constint nodeIndex) const;
// Returns the array index of the right child
int getRightChildIndex(int nodeIndex) const;
// Returns the array index of the parent node
int getParentIndex(int nodeIndex) const;
// Tests whether this node is a leaf
bool isLeaf(int nodeIndex) const;
// Converts the semiheap to a heap
void heapRebuild(int nodeIndex);
// Creates a heap from from unordered array
void heapCreate();
public:
ArrayMaxHeap();
ArrayMaxHeap(const ItemType someArray[], constint arraySize);
virtual ~ArrayMaxHeap();
bool isEmpty() const;
int getNumberOfNodes() const;
int getHeight() const;
ItemType peekTop() constthrow(PrecondViolatedExcep);
bool add(const ItemType& newData);
bool remove();
void clear();
};
// -------------------------------------------------------------------
// getLeftChildIndex: Returns the array index of the left child
// nodeIdex: is the index of the node
// returns the left node index
// -------------------------------------------------------------------
template<class ItemType>
int ArrayMaxHeap<ItemType>::getLeftChildIndex(constint nodeIndex) const
{
return (2 * nodeIndex) + 1;
}
// ----------------------------------------------------------------------
// getRightChildIndex: Returns the array index of the right child
// nodeIndex: is the index of the right node
// return the right node index
// ----------------------------------------------------------------------
template<class ItemType>
int ArrayMaxHeap<ItemType>::getRightChildIndex(constint nodeIndex) const
{
return (2 * nodeIndex) + 2;
}
// -------------------------------------------------------------------
// getParentIndex: Returns the parent node index
// nodeIndex: is the index of the parent node
// returns the array index of the parent node
// -------------------------------------------------------------------
template<class ItemType>
int ArrayMaxHeap<ItemType>::getParentIndex(constint nodeIndex) const
{
return (nodeIndex - 1) / 2;
}
//-------------------------------------------------------------
// isLeaf: Tells us if the node is a leaf
// nodeIdex: is the index of a node
// returns the left child index method
// ------------------------------------------------------------
template<class ItemType>
bool ArrayMaxHeap<ItemType>::isLeaf(constint nodeIndex) const
{
return (getLeftChildIndex(nodeIndex) >= itemCount);
}
//-------------------------------------------------------------------
// heapRebuild: Converts the semi-heap to a heap
// subTreeNodeIndex: the sub-tree array node index
// ------------------------------------------------------------------
template<class ItemType>
void ArrayMaxHeap<ItemType>::heapRebuild(constint subTreeNodeIndex)
{
// if the node is not a leaf
if (!isLeaf(subTreeNodeIndex))
{
// Get the left and right child index
int leftChildIndex = getLeftChildIndex(subTreeNodeIndex);
int largerChildIndex = leftChildIndex;
int rightChildIndex = getRightChildIndex(subTreeNodeIndex);
if (rightChildIndex < itemCount)
{
// if the right child index is greater than largest child index
if (items[rightChildIndex].priorityValue > items[largerChildIndex].priorityValue)
largerChildIndex = rightChildIndex; // set largest child index to right child index
}
// if the sub tree node is less than largest child index
if (items[subTreeNodeIndex].priorityValue < items[largerChildIndex].priorityValue)
{
std::swap(items[largerChildIndex], items[subTreeNodeIndex]); // swap the large child index and sub tree node
heapRebuild(largerChildIndex); // call on the heapRebuild method
}
}
}
// -------------------------------------------------
// heapCreate: creates a heap from an unsorted array
// ------------------------------------------------
template<class ItemType>
void ArrayMaxHeap<ItemType>::heapCreate()
{
// Create a heap from unsorted array
for (int index = itemCount / 2; index >= 0; index--)
{
heapRebuild(index); // call on the rebuild method
}
}
// ---------------------------------------------------------------------------
// ArrayMaxHeap: sets the number of items to the max capacity
//-----------------------------------------------------------------------------
template<class ItemType>
ArrayMaxHeap<ItemType>::ArrayMaxHeap() :itemCount(0), maxItems(DEFAULT_CAPACITY)
{
items = new ItemType[DEFAULT_CAPACITY];
}
// -------------------------------------------------------------------------------------
// ArrayMaxHeap: Allocats memory for the array and copy values
// someArray[]: an array of ItemType
// arraySize: the size of the array ItemType
// -------------------------------------------------------------------------------------
template<class ItemType>
ArrayMaxHeap<ItemType>::ArrayMaxHeap(const ItemType someArray[], constint arraySize) :
itemCount(arraySize), maxItems(2 * arraySize)
{
// Allocate the array
items = new ItemType[2 * arraySize];
// Copy the given values into the array
for (int i = 0; i < itemCount; i++)
items[i] = someArray[i];
// Reorganize the array into the heap
heapCreate();
}
// -----------------------------------------
// ~ArrayMaxHeap: delete the items of array
// -----------------------------------------
template<class ItemType>
ArrayMaxHeap<ItemType>::~ArrayMaxHeap()
{
delete[] items; // delete array of items
}
// ----------------------------------------------
// isEmpty: see if array is empty
// return itemCount when zero
// ----------------------------------------------
template<class ItemType>
bool ArrayMaxHeap<ItemType>::isEmpty() const
{
return itemCount == 0;
}
// ----------------------------------------------
// getHeight: gets the height of the node
// returns the height of the nodes
// --------------------------------------------
template<class ItemType>
int ArrayMaxHeap<ItemType>::getHeight() const
{
// Calculate the height
double y = log(itemCount + 1) / log(2);
return ceil(y);
}
// --------------------------------------------------
// getNumberOfNodes: gets the number of nodes
// returns the number of nodes
// ---------------------------------------------------
template<class ItemType>
int ArrayMaxHeap<ItemType>::getNumberOfNodes() const
{
return itemCount;
}
// --------------------------------------
// clear: removes all data from the heap
// --------------------------------------
template<class ItemType>
void ArrayMaxHeap<ItemType>::clear()
{
itemCount = 0;
}
// ---------------------------------------------------------
//peekTop: Gets the data that is in the top of this heap
// returns the the top of the heap
// ----------------------------------------------------------
template<class ItemType>
ItemType ArrayMaxHeap<ItemType>::peekTop() constthrow(PrecondViolatedExcep)
{
// If the heap is empty throw error
if (isEmpty())
throw PrecondViolatedExcep("Attempted peek into an empty heap.");
return items[0];
}
// ------------------------------------------------------
// add: add values to the heap
// newData: the new data to be added to heap
// returns if adding the new data was successful
// -------------------------------------------------------
template<class ItemType>
bool ArrayMaxHeap<ItemType>::add(const ItemType& newData)
{
bool isSuccessful = false;
// if itemCount is less than max items
if (itemCount < maxItems)
{
items[itemCount] = newData;
bool inPlace = false;
int newDataIndex = itemCount;
// While the new data index is greater than zero and not in place
while ((newDataIndex > 0) && !inPlace)
{
int parentIndex = getParentIndex(newDataIndex);
// If new dtata index is less than parent index
if (items[newDataIndex].priorityValue < items[parentIndex].priorityValue)
{
inPlace = true; // set inPlace to true
}
else
{
std::swap(items[newDataIndex], items[parentIndex]); // swap the index
newDataIndex = parentIndex; // set new data index to parent index
}
}
itemCount++; // count number of items
bool isSuccessful = true;
}
return isSuccessful;
}
// ------------------------------------
// remove: remove data from the heap
// returns if the removal was successful
// ------------------------------------
template<class ItemType>
bool ArrayMaxHeap<ItemType>::remove()
{
bool isSuccessful = false;
// if the heap is not empty
if (!isEmpty())
{
items[ROOT_INDEX] = items[itemCount - 1];
itemCount--;
heapRebuild(ROOT_INDEX);
bool isSuccessful = true;
}
return isSuccessful;
}
#endif
No. HeapPriorityQueue.cpp must'nt be set as a compilation unit. HeapPriorityQueue.h includes HeapPriorityQuere.cpp at the end (as Is aid above). HeapPriorityQueue.cpp doesn't include HeapPriorityQueue.h
When I get some time in the next couple of hours, I'll rework the code
ArrayMaxHeap.h also has the function implementations in the same file as the class definition. You should do the same for HeapPriorityQueue.h and then you don't need HeapPriorityQueue.cpp
/HeapInterface.h
#ifndef HEAP_iNTERFACE_
#define HEAP_INTERFACE_
#include <iostream>
template<class ItemType>
class HeapInterface
{
public:
// See if the heap is empty
virtualbool isEmpty() const = 0;
// Gets the number of nodes in this heap
virtualint getNumberOfNodes() const = 0;
// Gets the height of the nodes
virtualint getHeight() const = 0;
// Gets the data that is in the top of this heap
// For the maxHeap the data is the largest value in the heap
// For the minHeap the data is the smmallest value in the heap
virtual ItemType peekTop() const = 0;
// Adds new data to the heap
virtualbool add(const ItemType& newData) = 0;
// Removes the data that is at the top of the heap
virtualbool remove() = 0;
// Removes all data from the heap
virtualvoid clear() = 0;
// Destroys this heap and frees its assigned memory
virtual ~HeapInterface() { }
};
#endif
#ifndef ARRAY_MAX_HEAP_
#define ARRAY_MAX_HEAP_
#include "HeapInterface.h"
#include "PrecondViolatedExcept.h"
#include <math.h>
#include <stdio.h>
template<class ItemType>
class ArrayMaxHeap : public HeapInterface<ItemType>
{
private:
staticconstint ROOT_INDEX = 0; // Helps with readibility
staticconstint DEFAULT_CAPACITY = 21;
ItemType* items; // Array of heap items
int itemCount; // Current count of heap items
int maxItems; // Max capcity of the heap
// Returns the array index of the left child
int getLeftChildIndex(constint nodeIndex) const;
// Returns the array index of the right child
int getRightChildIndex(int nodeIndex) const;
// Returns the array index of the parent node
int getParentIndex(int nodeIndex) const;
// Tests whether this node is a leaf
bool isLeaf(int nodeIndex) const;
// Converts the semiheap to a heap
void heapRebuild(int nodeIndex);
// Creates a heap from from unordered array
void heapCreate();
public:
ArrayMaxHeap();
ArrayMaxHeap(const ItemType someArray[], constint arraySize);
virtual ~ArrayMaxHeap();
bool isEmpty() const;
int getNumberOfNodes() const;
int getHeight() const;
ItemType peekTop() const;// throw(PrecondViolatedExcep);
bool add(const ItemType& newData);
bool remove();
void clear();
};
// -------------------------------------------------------------------
// getLeftChildIndex: Returns the array index of the left child
// nodeIdex: is the index of the node
// returns the left node index
// -------------------------------------------------------------------
template<class ItemType>
int ArrayMaxHeap<ItemType>::getLeftChildIndex(constint nodeIndex) const
{
return (2 * nodeIndex) + 1;
}
// ----------------------------------------------------------------------
// getRightChildIndex: Returns the array index of the right child
// nodeIndex: is the index of the right node
// return the right node index
// ----------------------------------------------------------------------
template<class ItemType>
int ArrayMaxHeap<ItemType>::getRightChildIndex(constint nodeIndex) const
{
return (2 * nodeIndex) + 2;
}
// -------------------------------------------------------------------
// getParentIndex: Returns the parent node index
// nodeIndex: is the index of the parent node
// returns the array index of the parent node
// -------------------------------------------------------------------
template<class ItemType>
int ArrayMaxHeap<ItemType>::getParentIndex(constint nodeIndex) const
{
return (nodeIndex - 1) / 2;
}
//-------------------------------------------------------------
// isLeaf: Tells us if the node is a leaf
// nodeIdex: is the index of a node
// returns the left child index method
// ------------------------------------------------------------
template<class ItemType>
bool ArrayMaxHeap<ItemType>::isLeaf(constint nodeIndex) const
{
return (getLeftChildIndex(nodeIndex) >= itemCount);
}
// ------------------------------------------------------------------ -
// heapRebuild: Converts the semi-heap to a heap
// subTreeNodeIndex: the sub-tree array node index
// ------------------------------------------------------------------
template<class ItemType>
void ArrayMaxHeap<ItemType>::heapRebuild(constint subTreeNodeIndex)
{
// if the node is not a leaf
if (!isLeaf(subTreeNodeIndex))
{
// Get the left and right child index
int leftChildIndex = getLeftChildIndex(subTreeNodeIndex);
int largerChildIndex = leftChildIndex;
int rightChildIndex = getRightChildIndex(subTreeNodeIndex);
if (rightChildIndex < itemCount)
{
// if the right child index is greater than largest child index
if (items[rightChildIndex].priorityValue > items[largerChildIndex].priorityValue)
largerChildIndex = rightChildIndex; // set largest child index to right child index
}
// if the sub tree node is less than largest child index
if (items[subTreeNodeIndex].priorityValue < items[largerChildIndex].priorityValue)
{
std::swap(items[largerChildIndex], items[subTreeNodeIndex]); // swap the large child index and sub tree node
heapRebuild(largerChildIndex); // call on the heapRebuild method
}
}
}
// -------------------------------------------------
// heapCreate: creates a heap from an unsorted array
// ------------------------------------------------
template<class ItemType>
void ArrayMaxHeap<ItemType>::heapCreate()
{
// Create a heap from unsorted array
for (int index = itemCount / 2; index >= 0; index--)
{
heapRebuild(index); // call on the rebuild method
}
}
// ---------------------------------------------------------------------------
// ArrayMaxHeap: sets the number of items to the max capacity
//-----------------------------------------------------------------------------
template<class ItemType>
ArrayMaxHeap<ItemType>::ArrayMaxHeap() :itemCount(0), maxItems(DEFAULT_CAPACITY)
{
items = new ItemType[DEFAULT_CAPACITY];
}
// -------------------------------------------------------------------------------------
// ArrayMaxHeap: Allocats memory for the array and copy values
// someArray[]: an array of ItemType
// arraySize: the size of the array ItemType
// -------------------------------------------------------------------------------------
template<class ItemType>
ArrayMaxHeap<ItemType>::ArrayMaxHeap(const ItemType someArray[], constint arraySize) :
itemCount(arraySize), maxItems(2 * arraySize)
{
// Allocate the array
items = new ItemType[2 * arraySize];
// Copy the given values into the array
for (int i = 0; i < itemCount; i++)
items[i] = someArray[i];
// Reorganize the array into the heap
heapCreate();
}
// -----------------------------------------
// ~ArrayMaxHeap: delete the items of array
// -----------------------------------------
template<class ItemType>
ArrayMaxHeap<ItemType>::~ArrayMaxHeap()
{
delete[] items; // delete array of items
}
// ----------------------------------------------
// isEmpty: see if array is empty
// return itemCount when zero
// ----------------------------------------------
template<class ItemType>
bool ArrayMaxHeap<ItemType>::isEmpty() const
{
return itemCount == 0;
}
// ----------------------------------------------
// getHeight: gets the height of the node
// returns the height of the nodes
// --------------------------------------------
template<class ItemType>
int ArrayMaxHeap<ItemType>::getHeight() const
{
// Calculate the height
double y = log(itemCount + 1) / log(2);
returnstatic_cast<int>(ceil(y));
}
// --------------------------------------------------
// getNumberOfNodes: gets the number of nodes
// returns the number of nodes
// ---------------------------------------------------
template<class ItemType>
int ArrayMaxHeap<ItemType>::getNumberOfNodes() const
{
return itemCount;
}
// --------------------------------------
// clear: removes all data from the heap
// --------------------------------------
template<class ItemType>
void ArrayMaxHeap<ItemType>::clear()
{
itemCount = 0;
}
// ---------------------------------------------------------
//peekTop: Gets the data that is in the top of this heap
// returns the the top of the heap
// ----------------------------------------------------------
template<class ItemType>
ItemType ArrayMaxHeap<ItemType>::peekTop() const// throw(PrecondViolatedExcep)
{
// If the heap is empty throw error
if (isEmpty())
throw PrecondViolatedExcep("Attempted peek into an empty heap.");
return items[0];
}
// ------------------------------------------------------
// add: add values to the heap
// newData: the new data to be added to heap
// returns if adding the new data was successful
// -------------------------------------------------------
template<class ItemType>
bool ArrayMaxHeap<ItemType>::add(const ItemType& newData)
{
bool isSuccessful = false;
// if itemCount is less than max items
if (itemCount < maxItems)
{
items[itemCount] = newData;
bool inPlace = false;
int newDataIndex = itemCount;
// While the new data index is greater than zero and not in place
while ((newDataIndex > 0) && !inPlace)
{
int parentIndex = getParentIndex(newDataIndex);
// If new dtata index is less than parent index
if (items[newDataIndex].priorityValue < items[parentIndex].priorityValue)
{
inPlace = true; // set inPlace to true
} else
{
std::swap(items[newDataIndex], items[parentIndex]); // swap the index
newDataIndex = parentIndex; // set new data index to parent index
}
}
itemCount++; // count number of items
bool isSuccessful = true;
}
return isSuccessful;
}
// ------------------------------------
// remove: remove data from the heap
// returns if the removal was successful
// ------------------------------------
template<class ItemType>
bool ArrayMaxHeap<ItemType>::remove()
{
bool isSuccessful = false;
// if the heap is not empty
if (!isEmpty())
{
items[ROOT_INDEX] = items[itemCount - 1];
itemCount--;
heapRebuild(ROOT_INDEX);
bool isSuccessful = true;
}
return isSuccessful;
}
#endif
include "HeapPriorityQueue.h"
#include "PrecondViolatedExcept.h"
#include "Common.h"
#include <iostream>
#include <string>
int main()
{
HeapPriorityQueue<item> pqPtr;
item* p = new item[4];
// Set task and priority values to a number
p[0].task = "Do coding assignment.";
p[0].priorityValue = 5;
p[1].task = "Start the research paper.";
p[1].priorityValue = 5;
p[2].task = "Go to the gorcery store.";
p[2].priorityValue = 3;
p[3].task = "Watch a movie.";
p[3].priorityValue = 2;
// Add task and priority values to queue
for (int i = 0; i < 4; i++)
{
bool success = pqPtr.add(p[i]);
if (!success)
std::cout << "Failed to add " << p[i].task << " to the priority queue." << std::endl;
}
// Find the task with the largest priority
for (int i = 0; i < 4; i++)
{
try
{
std::cout << "The item witht the largest priority: " << pqPtr.peek().task << std::endl;
}
catch (PrecondViolatedExcep e)
{
std::cout << e.what() << std::endl;
}
// Remove funtion with largest priority
std::cout << "Call remove function" << std::endl;
pqPtr.remove();
}
//system("pause");
return 0;
}
Rebuild started...
1>------ Rebuild All started: Project: heap, Configuration: Release x64 ------
1>driver.cpp
1>Generating code
1>Previous IPDB not found, fall back to full compilation.
1>All 168 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
1>Finished generating code
1>heap.vcxproj -> c:\myprogs\heap.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========