



Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
The implementation of a binary tree template class in c++. The class includes various inner workings such as node definition, tree creation, destruction, and iteration. It also includes utility methods for finding the leftmost descendant, successor, and iterators for traversing the tree.
Typology: Study notes
1 / 7
This page cannot be seen from the preview
Don't miss anything!




1: # ifndef BINARY_TREE_H 2: # define BINARY_TREE_H 3: 4: /** Class for a binary tree. Updated: 17 November 2008 */ 5: # include
72: BTNode* root; // A reference to the root of the tree 73: size_t num_items; // The number of nodes in the tree 74: 75: public : 76: /** Construct a tree with zero nodes */ 77: Binary_Tree() : sentinel(createSentinel()), root(sentinel), num_items(0) { } 78: 79: /** Return size of the tree. */ 80: size_t size() const { return num_items; } 81: 82: /** Return true if tree is empty. */ 83: bool empty() const { return num_items == 0; } 84: 85: protected : 86: //--------------- utilities for housekeeping ------------------ 87: /** Factory function for instantiating a new node instance. */ 88: virtual BTNode* createNode() { 89: return new BTNode(); 90: } 91: 92: private : 93: BTNode* createSentinel() { 94: BTNode* temp = createNode(); 95: temp->linkLeft(temp); 96: temp->linkRight(temp); 97: return temp; 98: } 99: 100: protected : 101: BTNode* createLeaf( const Item_Type& the_data = Item_Type()) { 102: BTNode* temp = createNode(); 103: temp->data() = the_data; 104: temp->linkLeft(sentinel); 105: temp->linkRight(sentinel); 106: return temp; 107: } 108: 109: /** Clone this subtree, returning pointer to new root. 110: * Note that the parent of the new root is NULL. 111: */ 112: BTNode* cloneSubtree(BTNode* node) { 113: if (node->isEnd()) 114: return sentinel; // do not clone it 115: else { 116: BTNode* new_root = createLeaf(node->data()); 117: new_root->linkLeft(cloneSubtree(node->left())); 118: new_root->linkRight(cloneSubtree(node->right())); 119: return new_root; 120: } 121: } 122: 123: /** Destroy this node and all descendents. 124: * However it leaves the sentinel alone. 125: * The num_items is accurately decremented to reflect the changes. 126: */ 127: void destroySubtree(BTNode* node) { 128: if (!node->isEnd()) { 129: destroySubtree(node->left()); 130: destroySubtree(node->right()); 131: delete node; 132: num_items--; 133: } 134: } 135: 136: public : 137: /** Construct a tree with given item at root and copies of indicated subtrees. 138: * The original subtrees are not affected. 139: */ 140: Binary_Tree( const Item_Type& item, 141: const Binary_Tree<Item_Type>& left_subtree = Binary_Tree(), 142: const Binary_Tree<Item_Type>& right_subtree = Binary_Tree()) :
214: return node->parent(); // will be NULL when there is no successor 215: } 216: } 217: 218: public : 219: //--------------- iterator class ------------------ 220: class iterator { 221: friend class Binary_Tree<Item_Type>; // Give access to outer class. 222: 223: protected : 224: const Binary_Tree<Item_Type>* tree; 225: typename Binary_Tree<Item_Type>::BTNode* current; 226: 227: iterator( const Binary_Tree<Item_Type>* tree, BTNode* pos) 228: : tree(tree), current(pos) { } 229: 230: public : 231: /** Default constructor makes an invalid iterator. */ 232: iterator() : tree(NULL), current(NULL) { } 233: 234: const Item_Type& operator () const { 235: return current->data(); 236: } 237: 238: const Item_Type operator ->() const { 239: return ¤t->data(); 240: } 241: 242: bool operator ==( const iterator& other) const { 243: return (tree == other.tree && current == other.current); 244: } 245: 246: bool operator !=( const iterator& other) const { 247: return !(* this == other); 248: } 249: 250: bool isRoot() const { return current == tree->root; } 251: 252: bool hasLeft() const { return current->hasLeft(); } 253: 254: bool hasRight() const { return current->hasRight(); } 255: 256: bool hasParent() const { return current->hasParent(); } 257: 258: bool isLeaf() const { return current->isLeaf(); } 259: 260: iterator parent() const { 261: iterator result(tree, current->parent()); 262: if (!result.current) 263: result.current = tree->sentinel; 264: return result; 265: } 266: 267: iterator left() const { 268: return iterator(tree, current->left()); 269: } 270: 271: iterator right() const { 272: return iterator(tree, current->right()); 273: } 274: 275: iterator& operator ++() { // pre-increment version 276: current = findSuccessor(current); 277: if (!current) 278: current = tree->sentinel; 279: return * this ; 280: } 281: 282: iterator operator ++( int ) { // post-increment version 283: iterator fixed(* this ); 284: ++(* this );
285: return fixed; 286: } 287: 288: iterator& operator --() { // pre-increment version 289: if (current->isEnd()) 290: current = findRightmostDescendent(tree->getRoot().current); 291: else 292: current = findPredecessor(current); 293: return * this ; 294: } 295: 296: iterator operator --( int ) { // post-increment version 297: iterator fixed(* this ); 298: --(* this ); 299: return fixed; 300: } 301: }; // end of iterator class 302: 303: 304: //--------------- tree methods involving iterators ------------------ 305: iterator getRoot() const { 306: return iterator( this , root); 307: } 308: 309: iterator begin() const { 310: return iterator( this , findLeftmostDescendent(root)); 311: } 312: 313: iterator end() const { 314: return iterator( this , sentinel); 315: } 316: 317: protected : 318: //--------------- iterator-based mutators ------------------ 319: void resetData( const iterator& pos, const Item_Type& item) { 320: pos.current->data() = item; 321: } 322: 323: /** 324: * Replace the subtree rooted at this position by the given structure. 325: * By default, replaces the subtree with an empty tree. 326: * The given parameter is unaffected. 327: * Returns an iterator to the root of the newly created subtree. 328: */ 329: iterator replaceThisSubtree( const iterator& pos, 330: const Binary_Tree<Item_Type>& other=Binary_Tree()) { 331: BTNode* node = pos.current; 332: BTNode* clone = cloneSubtree(other.root); 333: BTNode* parent = node->parent(); 334: bool leftOrient = (parent && node == parent->left()); 335: 336: num_items += other.size(); 337: destroySubtree(node); 338: if (parent) { 339: if (leftOrient) 340: parent->linkLeft(clone); 341: else 342: parent->linkRight(clone); 343: } else { 344: root = clone; 345: } 346: 347: if (clone) 348: return iterator( this , clone); 349: else 350: return this ->end(); 351: } 352: 353: /** 354: * Replace the left subtree of this position by the given subtree. 355: * By default, replaces the subtree with empty subtree.
427: if (grand) { 428: if (grand->left() == p) 429: grand->linkLeft(node); 430: else 431: grand->linkRight(node); 432: } else { 433: root = node; 434: root->_parent = NULL; 435: } 436: } 437: } 438: 439: }; // End Binary_Tree 440: # endif