#ifndef BINARY_TREE_H #define BINARY_TREE_H /** Class for a binary tree. */ #include #include #include #include #include #include "BTNode.h" template class Binary_Tree { public: /** Construct an empty Binary_Tree. */ Binary_Tree() : root(NULL) {} /** Construct a Binary_Tree with two subtrees. @param the_data The data at the root @param left_child The left subtree @param right_child The right subtree */ Binary_Tree(const Item_Type& the_data, const Binary_Tree& left_child = Binary_Tree(), const Binary_Tree& right_child = Binary_Tree()): root(new BTNode(the_data, left_child.root, right_child.root)) {} /** Virtual destructor to avoid warnings */ virtual ~Binary_Tree() {} // Do nothing. /** Return the left subtree. */ Binary_Tree get_left_subtree() const { if (root == NULL) { throw std::invalid_argument("get_left_subtree on empty tree"); } return Binary_Tree(root->left); } /** Return the right subtree. */ Binary_Tree get_right_subtree() const { if (root == NULL) { throw std::invalid_argument("get_right_subtree on null tree"); } return Binary_Tree(root->right); } /** Return the data field of the root. @throws std::invalid_argument if empty tree */ const Item_Type& get_data() const { if (root == NULL) { throw std::invalid_argument("get_data on null tree"); } return root->data; } /** Indicate that this is the empty tree. */ bool is_null() const { return root == NULL; } /** Indicate that this tree is a leaf. */ bool is_leaf() const { if (root != NULL) { return root->left == NULL && root->right == NULL; } else return true; } /** Return a string representation of this tree. */ virtual std::string to_string() const { std::ostringstream os; if (is_null()) os << "NULL\n"; else { os << *root << '\n'; os << get_left_subtree().to_string(); os << get_right_subtree().to_string(); } return os.str(); } /** Return a string representation of the root */ std::string root_to_string() const { return root->to_string(); } /** Read a binary tree */ static Binary_Tree read_binary_tree(std::istream& in) { std::string next_line; getline(in, next_line); if (next_line == "NULL") { return Binary_Tree(); } else { Item_Type the_data; std::istringstream ins(next_line); ins >> the_data; Binary_Tree left = read_binary_tree(in); Binary_Tree right = read_binary_tree(in); return Binary_Tree(the_data, left, right); } } protected: // Protected constructor /** Construct a Binary_Tree with a given node as the root */ Binary_Tree(BTNode* new_root) : root(new_root) {} // Data Field BTNode* root; }; // End Binary_Tree // Overloading the ostream insertion operator. template std::ostream& operator<<(std::ostream& out, const Binary_Tree& tree) { return out << tree.to_string(); } // Overloading the istream extraction operator template std::istream& operator>>(std::istream& in, Binary_Tree& tree) { tree = Binary_Tree::read_binary_tree(in); return in; } #endif