/** * Binary tree class implementation * with DFS (various traversals) and BFS * CS 2240 * University of Vermont * Clayton Cafiero * 2020-Jun-20 */ #include // for DFS #include // for BFS #include // for find #include "binaryTree.h" /** * Node constructor * @param label */ Node::Node(std::string label) { this->label = label; this->left_child = nullptr; this->right_child = nullptr; } // Accessors /** * Get label * @return label of node (int) */ std::string Node::getLabel() const { return label; } /** * Get left child * @return pointer to left child */ Node* Node::getLeftChild() const { return left_child; } /** * Get right child * @return pointer to right child */ Node* Node::getRightChild() const { return right_child; } /** * Set right child * @param ptr to right child */ void Node::setRightChild(Node* ptr) { this->right_child = ptr; } /** * Set left child * @param ptr to left child */ void Node::setLeftChild(Node* ptr) { this->left_child = ptr; } /** * Binary tree constructor */ BinaryTree::BinaryTree(Node* root) { this->root = root; } BinaryTree::~BinaryTree() { BinaryTree::destroy(root); } /** * Recursively destroy the tree to prevent * memory leaks * * @param n */ void BinaryTree::destroy(Node* n) { if(n != nullptr) { destroy(n->getLeftChild()); destroy(n->getRightChild()); delete n; } } /** * DFS pre-order traversal */ std::vector BinaryTree::preorder() { std::stack s; std::vector v = std::vector(); s.push(root); v.push_back(root->getLabel()); while (! s.empty()) { Node* n = s.top(); Node* left = n->getLeftChild(); Node* right = n->getRightChild(); if(left != nullptr && std::find(v.begin(), v.end(), left->getLabel()) == v.end()) { s.push(left); v.push_back(left->getLabel()); } else if(right != nullptr && std::find(v.begin(), v.end(), right->getLabel()) == v.end()) { s.push(right); v.push_back(right->getLabel()); } else { s.pop(); } } return v; } /** * DFS post-order traversal */ std::vector BinaryTree::postorder() { std::stack s; std::vector v = std::vector(); s.push(root); while (! s.empty()) { Node* n = s.top(); Node* left = n->getLeftChild(); Node* right = n->getRightChild(); if(left != nullptr && std::find(v.begin(), v.end(), left->getLabel()) == v.end()) { s.push(left); } else if(right != nullptr && std::find(v.begin(), v.end(), right->getLabel()) == v.end()) { s.push(right); } else { v.push_back(n->getLabel()); s.pop(); } } return v; } /** * DFS in-order traversal */ std::vector BinaryTree::inorder() { std::stack s; std::vector v = std::vector(); s.push(root); while (! s.empty()) { Node* n = s.top(); Node* left = n->getLeftChild(); Node* right = n->getRightChild(); if(left != nullptr && std::find(v.begin(), v.end(), left->getLabel()) == v.end()) { s.push(left); } else { if (std::find(v.begin(), v.end(), n->getLabel()) == v.end()) { v.push_back(n->getLabel()); } if(right != nullptr && std::find(v.begin(), v.end(), right->getLabel()) == v.end()) { s.push(right); } else { s.pop(); } } } return v; } /** * BFS traversal */ std::vector BinaryTree::bfs() { std::queue q; std::vector v = std::vector(); q.push(root); v.push_back(root->getLabel()); while (! q.empty()) { Node* n = q.front(); Node* left = n->getLeftChild(); Node* right = n->getRightChild(); if(left != nullptr && std::find(v.begin(), v.end(), left->getLabel()) == v.end()) { q.push(left); v.push_back(left->getLabel()); } if(right != nullptr && std::find(v.begin(), v.end(), right->getLabel()) == v.end()) { q.push(right); v.push_back(right->getLabel()); } q.pop(); } return v; }