Heap assignment
files/Heap.h
#ifndef HEAP_H #define HEAP_H #include <vector> #include <stdexcept> // std::out_of_range #include <math.h> // pow() using namespace std; template<typename T> class Heap { private: vector<T> _items; // Main vector of elements for heap storage /** * Used to take unsorted data and heapify it */ void buildHeap() { for (int i = _items.size() / 2; i >= 0; i--) { percolateDown(i); } } /*********************************************************************/ /********************* Microassignment zone *************************/ /** * Percolates the item specified at by index down * into its proper location within a heap. * Used for dequeue operations and array to heap conversions * MA TODO: Implement percolateDown! */ void percolateDown(int index) { } /** * Percolate up from a given index to fix heap property * Used in inserting new nodes into the heap * MA TODO: Implement percolateUp */ void percolateUp( int current_position ) { } /************************** Microassigment zone DONE *********************/ public: /** * Default empty constructor */ Heap() { } /** * Constructor with a vector of elements */ Heap(const vector<T> &unsorted) { for (int i = 0; i < unsorted.size(); i++) { _items.push_back(unsorted[i]); } buildHeap(); } /** * Adds a new item to the heap */ void insert(T item) { int current_position = size(); // Get index location _items.push_back(item); // Add data to end percolateUp( current_position ); // Adjust up, as needed } /** * Returns the top-most item in our heap without * actually removing the item from the heap */ T& getFirst() { if( size() > 0 ) return _items[0]; else throw std::out_of_range("No elements in Heap."); } /** * Removes minimum value from heap and returns it to the caller */ T deleteMin() { int last_index = size() - 1; // Calc last item index int root_index = 0; // Root index (for readability) T min_item = _items[root_index]; // Keep item to return _items[root_index] = _items[last_index]; // Move last item to root _items.erase(_items.end() - 1); // Erase last element entry percolateDown(0); // Fix heap property return min_item; } /** * Returns true if heap is empty, else false */ bool isEmpty() const { return _items.size() == 0; } /** * Returns current quantity of elements in heap (N) */ int size() const { return _items.size(); } /** * Return heap data in order from the _items vector */ string to_s() const { string ret = ""; for(int i = 0; i < _items.size(); i++) { ret += to_string(_items[i]) + " "; } return ret; } /** * Print out the data in order from the _items vector */ void print() const { for(int i = 0; i < _items.size(); i++) { cout << _items[i] << " "; } } /** * Print out the data with array index details from the _items vector */ void printArray() const { for(int i = 0; i < _items.size(); i++) { cout << " [x] Heap element [" << i << "]. key=" << _items[i] << endl; } } /** * Print out the tree by levels (kinda pretty?) */ void printPretty() const { int rownum = 1; cout << " [x] Row #" << rownum << " - "; for( int i = 0; i < _items.size(); i++ ) { cout << _items[i] << " "; if( pow(2, rownum) - 1 == i + 1 ) { rownum++; cout << endl << " [x] Row #" << rownum << " - "; } } cout << endl; } }; #endif
files/MA-HeapPercolate(1).pdf
CptS 223 Micro Assignment #4 - Heap Percolating For this micro assignment, you must implement the following functions found inside Heap.h.
Note that our heap is a min-heap (smallest items at the top)!
void percolateDown(int index)
void percolateUp(int current_position)
These functions cause the items at the supplied locations to "percolate down" and “percolate up” the
heap until the min-heap property is satisfied. percolateDown is called on deleteMin operations; see
the deleteMin function inside Heap class to see how percolateDown is called. Note that we're being
good programmers and allowing the heap to percolate down at any point, not just the root! Doing so
allows us to evoke the percolate down functionality in other situations (e.g. buildHeap).
The percolateUp function is called on insert() calls and moves any given index up in the tree until it
satisfies the heap properties of our min heap.
I have tested this code on the EECS SSH server, ssh8. I used the command line:
g++ -g -Wall -std=c++0x main.cpp
You can run this with ‘make’, ‘make test’, and ‘make run’ as per usual
It built and runs properly. The tests for insert and delete currently fail, which is what you’re going to
fix.
Grading Your submission will be graded based on the following:
1. [10] Your solution builds, does not cause any runtime issues, and passes all test cases
Due Date This assignment must be submitted through Blackboard in a zip or tarball file no later than 11:59pm
on Monday, March 27th, 2017.
files/main.cpp
files/main.cpp
#include
<
iostream
>
#include
<
string
.
h
>
#include
"Heap.h"
/**
* Run a series of tests to evaluate the heap object
*/
void
heapTests
()
{
Heap
<
int
>
myHeap
;
myHeap
.
insert
(
890
);
myHeap
.
insert
(
567
);
myHeap
.
insert
(
456
);
myHeap
.
insert
(
921
);
myHeap
.
insert
(
678
);
myHeap
.
insert
(
123
);
myHeap
.
insert
(
234
);
myHeap
.
insert
(
345
);
myHeap
.
insert
(
750
);
// This should build a heap that looks like this:
// 123
// / \
// 345 234
// / \ / \
// 678 890 567 456
// / \
// 921 750
cout
<<
" [x] Current elements in the heap (should be low->high order): "
<<
endl
;
myHeap
.
printArray
();
cout
<<
" [x] Tree-ish form of the heap elements: "
<<
endl
;
myHeap
.
printPretty
();
cout
<<
endl
;
// Testing the insert & percolateUp behavior
cout
<<
" ***************** Insert testing ***********************"
<<
endl
;
cout
<<
" [X] Current heap order test after insert / percolateUp: "
<<
endl
;
cout
<<
" [x] Heap should be: 123 345 234 678 890 567 456 921 750"
<<
endl
;
cout
<<
" [t] Heap actually is: "
;
cout
<<
myHeap
.
to_s
();
if
(
myHeap
.
to_s
()
==
"123 345 234 678 890 567 456 921 750 "
)
{
cout
<<
"- PASS "
<<
endl
;
}
else
{
cout
<<
"- FAIL "
<<
endl
;
}
myHeap
.
insert
(
101
);
cout
<<
" [x] Heap should be: 101 123 234 678 345 567 456 921 750 890 "
<<
endl
;
cout
<<
" [t] Heap actually is: "
;
cout
<<
myHeap
.
to_s
();
if
(
myHeap
.
to_s
()
==
"101 123 234 678 345 567 456 921 750 890 "
)
{
cout
<<
"- PASS "
<<
endl
;
}
else
{
cout
<<
"- FAIL "
<<
endl
;
}
cout
<<
endl
;
// Testing the remove & percolateDown behavior
cout
<<
" ***************** Remove/Delete testing ****************"
<<
endl
;
cout
<<
" [X] Beginning to remove elements from the heap: "
<<
endl
;
cout
<<
" [*] Once percolateDown is done, these go low->high."
<<
endl
;
string acc
=
""
;
cout
<<
" [x] Order should be: 101 123 234 345 456 567 678 750 890 921"
<<
endl
;;
cout
<<
" [t] Order actually is: "
;
while
(
myHeap
.
isEmpty
()
==
false
)
{
int
top
=
myHeap
.
deleteMin
();
cout
<<
top
<<
" "
;
acc
+=
to_string
(
top
)
+
" "
;
}
if
(
acc
==
"101 123 234 345 456 567 678 750 890 921 "
)
{
cout
<<
"- PASS "
<<
endl
;
}
else
{
cout
<<
"- FAIL "
<<
endl
;
}
cout
<<
endl
;
cout
<<
" [x] Done. "
<<
endl
;
}
/**
* Main function for our heap and heap testing
*/
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
>
1
&&
!
strcmp
(
argv
[
1
],
"--test"
)
)
{
cout
<<
" [x] Running in test mode. "
<<
endl
;
heapTests
();
cout
<<
" [x] Program complete. "
<<
endl
;
}
else
{
cout
<<
" [x] Running in normal mode. "
<<
endl
;
cout
<<
" [!] Nothing to do in normal mode, so here's a helper: "
<<
endl
<<
endl
;
cout
<<
""
""
" ___.___ \n"
" (_]===* \n"
" o 0 \n"
" \n"
" _,-}}-._ \n"
" /\\ } /\\ \n"
" _|(0\\\\_ _/0) ___|_ \n"
" _|/ (__''__) |#####| \n"
" _|\\/ WVVVVW |#####| \n"
" \\ _\\ \\MMMM/_ .-----.###| \n"
" _|\\_\\ _ '---; \\_ |#####|###| \n"
" /\\ \\ _\\/ \\_ / \\ |#C++#|###| \n"
" / ( _\\/ \\ \\ |'VVV P |#####|###| \n"
" ( '-,._\\_.( 'VVV / (_/|\\_) |#####|###| \n"
" \\ / _) / _) (_/_ _\\_)|#####|###| \n"
" '....--''\\__vvv)\\__vvv)_____|_| |_|_|#####|###|____ldb\n"
;
cout
<<
endl
<<
" You should probably run 'make test' to test your program. "
<<
endl
;
}
}
files/Makefile
# # xxxx # # Variables GPP = g++ CFLAGS = -g -std=c++0x RM = rm -f BINNAME = heap # Shell gives make a full user environment # Adding this to PATH will find the newer g++ compiler on the EECS servers. SHELL := /bin/bash PATH := /opt/rh/devtoolset-3/root/usr/bin/:$(PATH) # Default is what happenes when you call make with no options # In this case, it requires that 'all' is completed default: all # All is the normal default for most Makefiles # In this case, it requires that build is completed all: build # build depends upon *.cpp, then runs the command: # g++ -g -std=c++0x -o bigFiveList build: main.cpp $(GPP) $(CFLAGS) -o $(BINNAME) main.cpp run: build ./$(BINNAME) test: build ./$(BINNAME) --test bigtest: build ./$(BINNAME) --test --withFuzzing # If you call "make clean" it will remove the built program # rm -f HelloWorld clean veryclean: $(RM) $(BINNAME)