Answer To: ass5-2/BinarySearchTree.cpp ass5-2/BinarySearchTree.cpp //...
Manoj answered on Jun 08 2021
ass5-2/BinarySearchTree.cpp
ass5-2/BinarySearchTree.cpp
// modified from Frank M. Carrano and Timothy M. Henry.
// modified by Matthieu Blanchet and Shashank Chennapragada
#include "BinarySearchTree.h"
#include
#include
using namespace std;
// BinaryNode constructor w/ item
// Pre: none
// Post: a binaryNode containing anItem is created
BinaryNode::BinaryNode(int anItem) : item(anItem) {}
//====================== Constructors/Destructors=============================
// Default constructor
// Pre: none
// Post: a Threaded binary search tree (TBST) has been created
BinarySearchTree::BinarySearchTree() = default;
// Constructor to generate nodes , generates n nodes from with values of 1 ,2,.
// .. n, adds these nodes to the binary tree such that the tree is balanced!
// Pre: nodeArr is number of nodes to add
// Post: a TBST had been created with n nodes
BinarySearchTree::BinarySearchTree(int nodeArr) {
if (nodeArr > 0) {
vector nodes(nodeArr);
for (int i = 0; i < nodeArr; i++) {
nodes[i] = i + 1;
}
addNodes(nodes, 0, nodeArr - 1);
}
}
// Recursive helper function for constructor that adds nodes from a vector to
// the tree
// Pre: the TBST is empty,nodes contains the nodes to add, front is the
// front of the vector, back is the back of the vector
// Post: the TBST contains the nodes in "nodes"
void BinarySearchTree::addNodes(vector nodes, int front, int back) {
//base case: if back is lower then front, the array is empty
if (back >= front) {
int midpoint = (back + front) / 2;
add(nodes[midpoint]);//add the halfway point
addNodes(nodes, front, midpoint - 1);
addNodes(nodes, midpoint + 1, back);
}
}
// Copy constructor
// Pre: tree is a TBST
// Post: our TBST is a deep copy of "tree"
BinarySearchTree::BinarySearchTree(const BinarySearchTree &tree) {
copyTree(tree.rootPtr);
}
// Recursive helper function for the copy constructor
// Pre: nodeTreePtr is the tree we need to copy values from
// Post: values from nodeTreePtr are copied to our TBST
void BinarySearchTree::copyTree(const BinaryNode* nodeTreePtr) {
if (nodeTreePtr != nullptr) {
int copyData = nodeTreePtr->item;
add(copyData);
if (!nodeTreePtr->threadLeft) {
copyTree(nodeTreePtr->leftChildPtr);
}
if (!nodeTreePtr->threadRight) {
copyTree(nodeTreePtr->rightChildPtr);
}
}
}
// Destructor
// Pre: none
// Post: the TBST's heap memory has been deallocated
BinarySearchTree:: ~BinarySearchTree() {
destroyTree(rootPtr);
}
// Recusive helper function for the destructor
// Pre: subtreePtr is the subtree we want to delete
// Post: subtreePtr and its children have been deleted
void BinarySearchTree::destroyTree(BinaryNode* subTreePtr) {
if (subTreePtr != nullptr) {
if (!subTreePtr->threadLeft || !subTreePtr->threadRight) {
if (!subTreePtr->threadLeft) {
destroyTree(subTreePtr->leftChildPtr);
}
if (!subTreePtr->threadRight) {
destroyTree(subTreePtr->rightChildPtr);
}
delete subTreePtr;
} else if (subTreePtr->threadLeft && subTreePtr->threadRight) {
delete subTreePtr;
}
}
}
//====================== end of Constructors/destructors=====================
// Adds a node to the tree, also updates the threads in the tree as necessary
// Pre: newData is the int to insert in our tree
// Post: our tree contains the node
bool BinarySearchTree::add(const int& newData) {
BinaryNode* newPtr = new BinaryNode(newData);
return placeNode(rootPtr, newPtr);
}
// Recursive helper function for add, determines where to place a node
// Pre: subTreePtr is the tree to add the node, newNodePtr is the node to add
// Post: newNodePtr has been added to subTreePtr
bool BinarySearchTree::placeNode(BinaryNode *subTreePtr,
BinaryNode *newNodePtr) {
if (subTreePtr == nullptr){ // if there's no root
rootPtr = newNodePtr; // set the root
rootPtr->threadLeft = true;
rootPtr->threadRight = true;
return true;
} else if(subTreePtr->item > newNodePtr->item) {
if(subTreePtr->threadLeft) { // base case there's a right thread!
// set the new node to have the thread
newNodePtr->threadLeft = true;
newNodePtr->leftChildPtr = subTreePtr->leftChildPtr;
newNodePtr->threadRight = true;
newNodePtr->rightChildPtr = subTreePtr;
subTreePtr->threadLeft = false;
subTreePtr->leftChildPtr = newNodePtr;
return true;
}
return placeNode(subTreePtr->leftChildPtr, newNodePtr); //not at the end
} else { // subtree <= newNode
// base case there's a right thread!
if (subTreePtr->threadRight) {
// set the new node to have the thread
newNodePtr->threadRight = true;
newNodePtr->rightChildPtr = subTreePtr->rightChildPtr;
newNodePtr->threadLeft = true;
newNodePtr->leftChildPtr = subTreePtr;
subTreePtr->threadRight = false;
subTreePtr->rightChildPtr = newNodePtr;
return true;
}
return placeNode(subTreePtr->rightChildPtr, newNodePtr);
}
return false;
}
// Removes a value from a threaded binary search tree,
// returns true if successful, false otherwise
// Pre: target is the int to remove from our TBST
// Post: the target has been removed from our TBST
bool BinarySearchTree::remove( const int& target) {
bool successful = false;
removeValue(rootPtr, target, nullptr, successful, false);
return successful;
}
// Recursive helper method for remove(), recursively locates the node to delete
// and calls
// Pre: subTreePtr is the tree where we want to remove target, parent is the
// parent of subTreePtr, success indicates if we have removed the node correctly
// isLeft indicates if the parent is to the left of the child (true if so,
// false otherwise)
// Post: target has been removed from subTreePtr
BinaryNode* BinarySearchTree::removeValue(BinaryNode* subTreePtr, int target,
BinaryNode* parent, bool& success,
bool isleft) {
BinaryNode* tempPtr = nullptr; // probably not necessary leave till testing
if (subTreePtr == nullptr) { //check if rootptr is initialized
return nullptr;
} else if (subTreePtr->item == target) { // found the target
subTreePtr = removeNode(subTreePtr, isleft, parent); // Remove the item
success = true;
return subTreePtr;
} else if (subTreePtr->threadRight && subTreePtr->threadLeft) {
//hit a leaf without finding the target
return subTreePtr;
} else if (subTreePtr->item > target) {
// Search the left subtree
tempPtr = removeValue(subTreePtr->leftChildPtr, target, subTreePtr,
success, false);
subTreePtr->leftChildPtr = tempPtr;
return subTreePtr;
} else {
// Search the right subtree
tempPtr = removeValue(subTreePtr->rightChildPtr, target, subTreePtr,
success , true);
subTreePtr->rightChildPtr = tempPtr;
return subTreePtr;
}
}
// Recursive helper for removeValue()
// Pre: RemNode is the node to be deleted, isLeft is the location of the parent
// left of remNode if true, right otherwise, parent is the parent of remNode
// Post: remNode has been deleted and surrounding threads have been updated
BinaryNode* BinarySearchTree::removeNode(BinaryNode* remNode, bool isLeft,
BinaryNode* parent) {
BinaryNode* tempPtr;
BinaryNode* tempPtr2; // for rethreading
if ((remNode->threadLeft) && (remNode->threadRight)) { // is N a leaf?
if (isLeft) {
tempPtr = remNode->rightChildPtr;
// pass back the right pointer status
} else {
tempPtr = remNode->leftChildPtr;
// pass back the left pointer status
}
if (parent != nullptr) {// if there's a parent, it needs to inherit
// the child's threadedness
if (isLeft) {
parent->threadRight = remNode->threadRight;
} else {
parent->threadLeft = remNode->threadLeft;
}
}
delete remNode;
remNode = nullptr;
return tempPtr;
} else if ((remNode->threadRight) || (remNode->threadLeft)) {
// N has 1 child
// C replaces N as the child of N's parent
// is the child in the left branch?
if (remNode->threadRight) {
tempPtr = remNode->leftChildPtr;
tempPtr2 = tempPtr;
while (tempPtr2->rightChildPtr != remNode) {
// runs till tempPtr2 points w/ thread to the Node to be deleted
tempPtr2 = tempPtr2->rightChildPtr;
}
tempPtr2->rightChildPtr = remNode->rightChildPtr;
} else { // child is in the right branch
tempPtr = remNode->rightChildPtr;
tempPtr2 = tempPtr;
while (tempPtr2->leftChildPtr != remNode) {
// runs till tempPtr2 points w/ thread to the Node to be deleted
tempPtr2 = tempPtr2->leftChildPtr;
}
tempPtr2->leftChildPtr = remNode->leftChildPtr;
}
delete remNode;
remNode = nullptr;
return tempPtr; // needed to reconnect child nodes
} else {
// N has two children!
// we need to delete the leftmost node of the right node of N
// and insert that node's value into N
int val;
bool rightThread;
bool isLeft = true;
tempPtr = removeLeftMostNode(remNode->rightChildPtr,
val, isLeft, rightThread);
remNode->rightChildPtr = tempPtr;
if (isLeft) { //should we inherit the right threadedness
remNode->threadRight = rightThread;
}
remNode->item = val;
return remNode;
}
}
// Recursive helper for removeNode()
// Removes the leftmost node i...