the assignment is asking for AVL tree implementation
Hi Buddy, i was wondering if you could do this assignment ?For this project, we will be implementing functions of an AVL tree. The tree will act as a BST with integer keys (which are Comparable types) and must maintain the AVL nature as you insert and delete nodes. This archive includes a working AVL tree implementation, but does not do several things:Do inserts into the tree with integersYou’ll see the vector inserts used in the test code, that’s calling your codeMaintain the heights of nodes after an insertCheck heights of subtrees and do rotations as appropriate to keep the tree balancedSearch the tree to see if it contains a given nodeReturn the size (node count) in the treeRemove a node when given a keyReturn whether the tree is empty or notPrint out the tree in pre-, in-, and post- orderImplement the makeEmpty function for the destructorYour assignment is to add these features to the provided code. There are several notes in AvlTree.h about where you need to fill in the stubbed functions or replace/update the ones that are there, notably in insert, remove, contains, height, pre-, in-, post- print functions. Any function that has “TODO” in the comments is one that you’ll need to look at. Feel free to add any additional private member functions to AvlTree.h as you see fit. The starter code compiles and runs on the EECS SSH servers just fine. You can use that as a starting point for you own work. You will need to compile it using the provided Makefile. I have committed the project to your Git repository under the “PA1” branch.This makefile has one extra target for a big fuzzing test. You’ll need to do the full fuzzing test once you have both insert and remove implemented by executing ‘make bigtest’. The fuzzing test will do many random inserts and ⅓ as many deletes. This kind of test is called fuzzing because it’s trying many random input values to a given algorithm to see if anything breaks. In this case, we’ll make a tree of up to 3000 nodes and just seeing if it breaks.Expected OutputYour code must compile on the EECS servers, though you can do your development on other systems and do final tests on the EECS machines if you like.Your program will be tested first by doing this series of commands:makemake testmake bigtestmake cleanThen we’ll inspect the source code for quality. Structure, indentation, naming, commenting, cleanliness, consistency.Grading CriteriaYour assignment will be judged by the following criteria:[80] Code operational success. Your code compiles, executes, and passes the tests.[10] Your code is well documented and generally easy to read.[10] Your program intelligently uses classes when appropriate and generally conforms to good OOP design (i.e. everything isn't slapped into main). the files:Avltree.h#ifndef AVL_TREE_H#define AVL_TREE_H
#include "dsexceptions.h"#include <iostream> // For NULL#include <vector>#include <algorithm> // For max() functionusing namespace std;
// AvlTree class//// CONSTRUCTION: with ITEM_NOT_FOUND object used to signal failed finds//// ******************PUBLIC OPERATIONS*********************// int size( ) --> Quantity of elements in tree// int height( ) --> Height of the tree (null == -1)// void insert( x ) --> Insert x// void insert( vector<T> ) --> Insert whole vector of values// void remove( x ) --> Remove x (unimplemented)// bool contains( x ) --> Return true if x is present// Comparable findMin( ) --> Return smallest item// Comparable findMax( ) --> Return largest item// boolean isEmpty( ) --> Return true if empty; else false// void makeEmpty( ) --> Remove all items// void printTree( ) --> Print tree in sorted (in) order// void printPreOrder( ) --> Print tree in pre order// void printPostOrder( ) --> Print tree in post order// void printInOrder( ) --> Print tree in *in* order// ******************ERRORS********************************// Throws UnderflowException as warranted
template <typename Comparable>class AvlTree{ public: AvlTree( ) : root( NULL ) { }
AvlTree( const AvlTree & rhs ) : root( NULL ) { *this = rhs; }
~AvlTree( ) { cout << " [!] Destructor called." << endl; makeEmpty( ); }
/** * Find the smallest item in the tree. * Throw UnderflowException if empty. */ const Comparable & findMin( ) const { if( isEmpty( ) ) throw UnderflowException( ); return findMin( root )->element; }
/** * Find the largest item in the tree. * Throw UnderflowException if empty. */ const Comparable & findMax( ) const { if( isEmpty( ) ) throw UnderflowException( ); return findMax( root )->element; }
/** * Returns true if x is found in the tree. */ bool contains( const Comparable & x ) const { return contains( x, root ); }
/** * Test if the tree is logically empty. * Return true if empty, false otherwise. * TODO: Implement */ bool isEmpty( ) const { return false; // so not correct }
/** * Return number of elements in tree. */ int size( ) { return size( root ); }
/** * Return height of tree. * Null nodes are height -1 */ int height( ) { return height( root ); }
/** * Print the tree contents in sorted order. */ void printTree( ) const { if( isEmpty( ) ) cout << "Empty tree" << endl; else printInOrder( root ); }
/** * Print the tree contents in sorted order. */ void printInOrder( ) const { if( isEmpty( ) ) cout << "Empty tree" << endl; else printInOrder( root ); }
/** * Print the tree contents in pre order. */ void printPreOrder( ) const { if( isEmpty( ) ) cout << "Empty tree" << endl; else printPreOrder( root ); }
/** * Print the tree contents in post order. */ void printPostOrder( ) const { if( isEmpty( ) ) cout << "Empty tree" << endl; else printPostOrder( root ); }
/** * Make the tree logically empty. */ void makeEmpty( ) { makeEmpty( root ); }
/** * Insert x into the tree; duplicates are ignored. */ void insert( const Comparable & x ) { insert( x, root ); }
/** * Insert vector of x's into the tree; duplicates are ignored. */ void insert( vector<Comparable> vals) { for( auto x : vals ) { insert( x, root ); } }
/** * Remove x from the tree. Nothing is done if x is not found. * TODO: Implement */ void remove( const Comparable & x ) { //cout << "[!] Sorry, remove unimplemented; " << x << " still present" << endl; }
/** * Deep copy. - or copy assignment operator * Will be in part II */ const AvlTree & operator=( const AvlTree & rhs ) { cout << " [!] Copy *assignment* operator called." << endl; return *this; }
/*****************************************************************************/ private: struct AvlNode { Comparable element; AvlNode *left; AvlNode *right; int height;
AvlNode( const Comparable & theElement, AvlNode *lt, AvlNode *rt, int h = 0 ) : element( theElement ), left( lt ), right( rt ), height( h ) { } };
AvlNode *root;
/** * Internal method to count nodes in tree * TODO: Implement */ int size( AvlNode * & t ) { return(-1); }
/** * Internal method to insert into a subtree. * x is the item to insert. * t is the node that roots the subtree. * Set the new root of the subtree. * TODO: Implement */ void insert( const Comparable & x, AvlNode * & t ) { // Definitely to do }
/** * Internal method to find the smallest item in a subtree t. * Return node containing the smallest item. * You'll need this for deletes * TODO: Implement */ AvlNode * findMin( AvlNode *t ) const { return t; // placeholder }
/** * Internal method to find the largest item in a subtree t. * Return node containing the largest item. * TODO: Implement */ AvlNode * findMax( AvlNode *t ) const { return t; // placeholder }
/** * Internal method to test if an item is in a subtree. * x is item to search for. * t is the node that roots the tree. * TODO: Implement */ bool contains( const Comparable & x, AvlNode *t ) const { return false; // Lolz }
/******************************************************/
/** * Internal method to make subtree empty. * TODO: implement for destructor * */ void makeEmpty( AvlNode * & t ) { cout << " [!] makeEmpty not implemented " << endl; }
/** * Internal method to print a subtree rooted at t in sorted order. * TODO: Implement */ void printInOrder( AvlNode *t ) const { cout << " [!] Printing In Order"; }
/** * Internal method to print a subtree rooted at t in pre order. * TODO: Implement */ void printPreOrder( AvlNode *t ) const { cout << " [!] Printing Pre order"; }
/** * Internal method to print a subtree rooted at t in post order. * TODO: Implement */ void printPostOrder( AvlNode *t ) const { cout << " [!] Printing post order"; }
/** * Internal method to clone subtree. */ AvlNode * clone( AvlNode *t ) const { if( t == NULL ) return NULL; else return new AvlNode( t->element, clone( t->left ), clone( t->right ), t->height ); }
// Avl manipulations /** * Return the height of node t or -1 if NULL. * TODO: Implement */ int height( AvlNode *t ) const { return(-2); // DEFINITELY not true }
int max( int lhs, int rhs ) const { return lhs > rhs ? lhs : rhs; }
/** * Rotate binary tree node with left child. * For AVL trees, this is a single rotation for case 1. * Update heights, then set new root. * TODO: Implement */ void rotateWithLeftChild( AvlNode * & k2 ) { }
/** * Rotate binary tree node with right child. * For AVL trees, this is a single rotation for case 4. * Update heights, then set new root. * TODO: Implement */ void rotateWithRightChild( AvlNode * & k1 ) { }
/** * Double rotate binary tree node: first left child. * with its right child; then node k3 with new left child. * For AVL trees, this is a double rotation for case 2. * Update heights, then set new root. * TODO: Implement */ void doubleWithLeftChild( AvlNode * & k3 ) { }
/** * Double rotate binary tree node: first right child. * with its left child; then node k1 with new right child. * For AVL trees, this is a double rotation for case 3. * Update heights, then set new root. * TODO: Implement */ void doubleWithRightChild( AvlNode * & k1 ) { }};
#endifAvlTreeTesting.h#include "AvlTree.h"#include <iostream>#include <string.h>
/*****************************************************************************/// Do lots of random inserts and deletes. This is a fuzzing testvoid test_BigTreeFuzzing() { /* BIGGER test of your AVL tree! */ cout << " [t] Big Tree Fuzzing test."; vector<int> incVals; AvlTree<int> bigTree; srand (time(NULL)); for( int i = 0; i < 3000; i++ ) { int newVal = rand() % 900000; // Generate new integer to insert into tree bool skip = false; for( int j = 0; j < incVals.size(); j++ ){ // Very dumb search! if( incVals[j] == newVal ){ skip = true; j = incVals.size(); } } if( !skip ){ bigTree.insert(newVal); incVals.push_back(newVal); }
if( i % 3 == 0 ){ // Delete a random element every 3 inserts int remIndex = rand() % incVals.size(); bigTree.remove( incVals[remIndex] ); incVals.erase(incVals.begin() + remIndex); } } cout << " - fuzzing test complete. " << endl;}
void test_empty() { AvlTree<int> myTree; cout << " [t] Testing isEmpty() interface"; if( myTree.isEmpty() ) { cout << " - Pass" << endl; } else { cout << " - Fail" << endl; }}
void test_size() { AvlTree<int> myTree; cout << " [t] Testing size() interface..." << endl;; cout << " [t] size() when empty: " << myTree.size() << " - "; (myTree.size() == 0) ? cout << "Pass" : cout << "Fail"; cout << endl;
vector<int> vals = { 10, 5, 23, 3, 7, 30, 1 }; // Give us some data! myTree.insert( vals ); cout << " [t] size() with " << vals.size() << " values: " << myTree.size() << " - "; (vals.size() == myTree.size()) ? cout << "Pass" : cout << "Fail"; cout << endl;
myTree.remove( 10 ); // Remove the root, what about now? cout << " [t] size() with " << vals.size() - 1<< " values: " << myTree.size() << " - "; (vals.size() - 1 == myTree.size()) ? cout << "Pass" : cout << "Fail"; cout << endl;}
void test_height() { AvlTree<int> myTree; vector<int> vals = { 10, 5, 23, 3, 7, 30, 1 }; // Give us some data! cout << " [t] Testing tree heights" << endl; cout << " [t] Height of empty: " << myTree.height() << " - "; (myTree.height() == -1) ? cout << "Pass" : cout << "Fail"; cout << endl;
myTree.insert(vals); cout << " [t] Height of filled (3): " << myTree.height() << " - "; (myTree.height() == 3) ? cout << "Pass" : cout << "Fail"; cout << endl;}
void test_prints() { AvlTree<int> myTree; vector<int> vals = { 10, 5, 23, 3, 7, 30, 1 }; // Give us some data! myTree.insert(vals); cout << " [t] Testing tree print orders: " << endl;
cout << " [t] In Order: \t"; myTree.printInOrder(); cout << endl;
cout << " [t] Pre Order:\t"; myTree.printPreOrder(); cout << endl;
cout << " [t] Post Order:\t"; myTree.printPostOrder(); cout << endl;}
void test_insert(){ AvlTree<int> myTree; cout << " [t] Testing tree basic inserts: " << endl; myTree.insert(20); myTree.insert(10); myTree.insert(5); // Forces right rotate cout << " [t] Should be: \t10 5 20" << endl; cout << " [t] Pre Order: \t"; myTree.printPreOrder(); cout << endl;
myTree.insert(30); myTree.insert(40); // Forces left rotate cout << " [t] Should be: \t10 5 30 20 40" << endl; cout << " [t] Pre Order: \t"; myTree.printPreOrder(); cout << endl;
myTree.insert(15); // Forces Right-Left double rotate cout << " [t] Should be: \t20 10 5 15 30 40" << endl; cout << " [t] Pre Order: \t"; myTree.printPreOrder(); cout << endl;
myTree.insert(13); myTree.insert(14); // Forces Left-Right double rotate cout << " [t] Should be: \t20 10 5 14 13 15 30 40" << endl; cout << " [t] Pre Order: \t"; myTree.printPreOrder(); cout << endl;}
void test_contains() { AvlTree<int> myTree; vector<int> vals = { 10, 5, 23, 3, 7, 30, 1 }; // Give us some data! myTree.insert( vals ); cout << " [t] Testing contains:" << endl; cout << " [t] Searching for: 7 (is in tree)"; (myTree.contains(7)) ? cout << " - pass" : cout << " - fail"; cout << endl;
cout << " [t] Searching for: 15 (not in tree)"; (!myTree.contains(15)) ? cout << " - pass" : cout << " - fail"; cout << endl;}
/** * Testing the remove() function */void test_remove() { AvlTree<int> myTree; vector<int> vals = { 10, 5, 23, 3, 7, 30, 1 }; // Give us some data! myTree.insert( vals ); cout << " [t] Testing remove():" << endl; cout << " [t] Searching for: 7 (is in tree)"; (myTree.contains(7)) ? cout << " - pass" : cout << " - fail"; cout << endl;
cout << " [x] Removing 7 from tree. " << endl; myTree.remove(7); cout << " [t] Searching for: 7 (is not in tree)"; (!myTree.contains(7)) ? cout << " - pass" : cout << " - fail"; cout << endl;
}
/* * Testing features of your AVL Tree implementation */int avlTreeTests( bool fuzzing ){ cout << " [x] Starting AVL tree test. " << endl; test_empty(); // empty() interface working? test_size(); // size() interface working properly? test_height(); // height() working properly? test_prints(); // Print: preorder, postorder, inorder, levelorder test_insert(); // Insert test test_contains(); // Testing contains interface test_remove(); // Test of removing nodes via remove() if( fuzzing ) test_BigTreeFuzzing(); //Big tree fuzzing test
return(0);}Makefile # VariablesGPP = g++CFLAGS = -g -std=c++11RM = rm -fBINNAME = avltree
# Shell gives make a full user environment# Adding this to PATH will find the newer g++ compiler on the EECS servers.SHELL := /bin/bashPATH := /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 completeddefault: all
# All is the normal default for most Makefiles# In this case, it requires that build is completedall: build
# build depends upon *.cpp, then runs the command:# g++ -g -std=c++0x -o bigFiveListbuild: 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 HelloWorldclean veryclean: $(RM) $(BINNAME)dsexception.h#ifndef DS_EXCEPTIONS_H#define DS_EXCEPTIONS_H
class UnderflowException { };class IllegalArgumentException { };class ArrayIndexOutOfBoundsException { };class IteratorOutOfBoundsException { };class IteratorMismatchException { };class IteratorUninitializedException { };
#endifmain.cpp#include <iostream>#include <cstdlib>#include <string.h>#include "AvlTree.h"#include "AvlTreeTesting.h"using namespace std;
/* * Main function for test or use */int main( int argc, char* argv[] ){ int retState = 0; // Note: If you call this program like this: ./avltree --test // it will call the test function bool is_test_mode = false; bool is_fuzzing_test_mode = false; for( int i = 0; i < argc; i++ ) { if( !strcmp(argv[i], "--test" ) ) { cout << " [x] Enabling test mode. " << endl; is_test_mode = true; } else if( !strcmp(argv[i], "--withFuzzing" ) ) { cout << " [x] Enabling fuzzing tests. " << endl; is_fuzzing_test_mode = true; } } if( is_test_mode || is_fuzzing_test_mode ) { retState = avlTreeTests( is_fuzzing_test_mode ); // From AvlTreeTesting.h } else { cout << " [x] Running in normal mode. " << endl; cout << " [!] Nothing to do in normal mode so here's a helicopter: " << endl; cout << " ___.___\n (_]===*\n o 0" << endl; cout << endl << " You should probably run 'make test' to test your program. " << endl; cout << " This program also has a fuzzing test with 'make bigtest' to test your program. " << endl; } cout << " [x] Program complete. " << endl; return(retState);}