#ifndef TREE_H_ #define TREE_H_ 1 // Massingill, Berna L. and Oldham, Jeffrey D. // 2000 April 04 // CS1321 // A Recursive Binary Tree Class // In a Tree, values with type T are stored at all nodes, not just // leaves. Only binary trees are supported. See Knuth, vol.~1, for // a trick how to use binary trees to store trees with arbitrary // numbers of children. // (c) 2000 Berna L. Massingill and Jeffrey D. Oldham // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Loosely adapted from Seq template class code, available // from ftp://ftp.aw.com/cp/koenig/code.tar.Z // in conjunction with the book \emph{Ruminations on C++}. template class Tree { private: class TreeNode { public: unsigned int use; const ItemType itm; TreeNode* const lft; TreeNode* const rt; TreeNode(const ItemType& i, TreeNode* const l = 0, TreeNode* const r = 0) : use(1), itm(i), lft(l), rt(r) { if (l) ++l->use; if (r) ++r->use; } }; public: Tree(): root(0) { } explicit Tree(const ItemType& i, const Tree& l = Tree(), const Tree& r = Tree()) : root(new TreeNode(i, l.root, r.root)) { } Tree(const Tree& t) : root(t.root) { if (root) ++root->use; } explicit Tree(TreeNode* const t) : root(t) { if (t) ++t->use; } ~Tree() { destroy(root); } Tree& operator=(const Tree& s) { if (s.root) ++s.root->use; destroy(root); root = s.root; return *this; } const ItemType & item() const { if (root) return root->itm; else throw "item of an empty Tree"; } Tree left() const { if (root) return Tree(root->lft); else throw "left of an empty Tree"; } Tree right() const { if (root) return Tree(root->rt); else throw "right of an empty Tree"; } bool empty(void) const { return !root; } operator bool(void) const { return !empty(); } private: TreeNode* root; void destroy(TreeNode* const root) { if (root && (--root->use == 0)) { destroy(root->lft); destroy(root->rt); delete root; } } }; #endif // TREE_H_