BFLibCPP 0.1
CPP Library
Loading...
Searching...
No Matches
bintree.hpp
Go to the documentation of this file.
1
6#ifndef BINTREE_HPP
7#define BINTREE_HPP
8
9#include "access.hpp"
10#include "delete.hpp"
11#include "object.hpp"
12#include <iostream>
13#include "list.hpp"
14#include "stack.hpp"
15
16namespace BF {
17
23template <typename T, typename S = int> class BinTree : public Object {
24public:
25 // TODO: rename BinNode to Node
26 class BinNode : public Object {
27 friend class BinTree<T,S>;
28 public:
29 T object() const {
30 return this->_obj;
31 }
32
33 virtual const BinNode * left() const { return this->_left; }
34 virtual const BinNode * right() const { return this->_right; }
35 const BinNode * parent() const { return this->_parent; }
36
37 // True if we have no childred
38 virtual bool isLeaf() const {
39 return this->childCount() == 0;
40 }
41
42 // Is root if we have no parent
43 bool isRoot() const {
44 return (this->_parent == NULL);
45 }
46
55 char childType() const {
56 if (!this->_parent) return 0;
57 else {
58 if (this->_parent->_left == this) return -1;
59 else if (this->_parent->_right == this) return 1;
60 else return 0;
61 }
62 }
63
64 protected:
66 this->_obj = 0;
67 this->_left = 0;
68 this->_right = 0;
69 this->_parent = 0;
70 this->_location = 0;
71 }
72
73 BinNode(T object) : BinNode() {
74 this->_obj = object;
75 }
76
77 virtual ~BinNode() {
78 this->_left = 0;
79 this->_right = 0;
80 this->_parent = 0;
81 this->_location = 0;
82 }
83
84 // Returns parent of parent
85 // Null if no parent
86 virtual BinNode * grandParent() {
87 if (this->_parent) return this->_parent->_parent;
88 return NULL;
89 }
90
91 // Returns parent's sibling
92 virtual BinNode * pibling() {
93 BinNode * gp = NULL;
94
95 if ((gp = this->grandParent()) != NULL) {
96 if (gp->_left == this->_parent) return gp->_right;
97 else return gp->_left;
98 }
99
100 return NULL;
101 }
102
103 // Returns our sibling
104 virtual BinNode * sibling() {
105 switch (this->childType()) {
106 case 0:
107 return NULL;
108 case -1:
109 return this->_parent->_right;
110 case 1:
111 return this->_parent->_left;
112 default:
113 return NULL;
114 }
115 }
116
117 virtual unsigned char childCount() const {
118 if (this->_left && this->_right) {
119 return 2;
120 } else if (this->_left || this->_right) {
121 return 1;
122 } else return 0;
123 }
124
125 // Returns number of levels we are from root
126 int level() const {
127 return this->level(this->_parent, 0);
128 }
129
130 virtual void print() const {
131 int lvl = this->level();
132
133 for (int i = 1; i <= lvl; i++) {
134 if (i == lvl) {
135 if (!this->isRoot()) std::cout << " |";
136 std::cout << "----";
137 } else {
138 if (!this->isRoot()) {
139 if (this->childType() != 0) std::cout << " |";
140 else std::cout << " ";
141 }
142 std::cout << " ";
143 }
144 }
145
146 std::cout << "[" << this->_obj << "]" << std::endl;
147 }
148
149 // Makes shallow copy of us
150 virtual BinNode * clone() {
151 return new BinNode(*this);
152 }
153
154 // Sets left's parent if nonull
155 virtual void setLeft(BinNode * left) {
156 this->_left = left;
157 if (this->_left) {
158 this->_left->_parent = this;
159 this->_left->_location = &this->_left;
160 }
161 }
162
163 // Sets right's parent if nonull
164 virtual void setRight(BinNode * right) {
165 this->_right = right;
166 if (this->_right) {
167 this->_right->_parent = this;
168 this->_right->_location = &this->_right;
169 }
170 }
171
172 virtual BinNode * left() { return this->_left; }
173 BinNode ** leftAddr() { return &this->_left; }
174
175 virtual BinNode * right() { return this->_right; }
176 BinNode ** rightAddr() { return &this->_right; }
177
178 // Wondering if I want to make accessors for this
180
185
186 // Holds object
188
189 private:
190
191 // recursively executes until we reach root
192 int level(BinNode * node, int level) const {
193 if (node) return this->level(node->_parent, ++level);
194 else return level;
195 }
196
197 // Child node pointers
198 BinNode * _left;
199 BinNode * _right;
200 };
201
207 class Iterator : public Object {
208 friend class BinTree<T,S>;
209 public:
210
211 virtual ~Iterator() {
212
213 }
214
218 T current() { return this->_st.top()->object(); }
219
225 int next() {
226 BinNode * curr = this->_st.top()->right();
227 int result = this->_st.pop();
228
229 if (!result) {
230 result = this->setCurrent(curr);
231 }
232
233 return result;
234 }
235
239 bool finished() { return this->_st.empty(); }
240
241 protected:
242
246 virtual int setCurrent(BinNode * node) {
247 if (!node) return 1;
248 else {
249 int result = this->_st.push(node);
250
251 if (!result && node->left())
252 return this->setCurrent(node->left());
253 else return result;
254 }
255 }
256
258
263 };
264
266 this->_root = NULL;
267 this->_compare = NULL;
268 this->_count = 0;
269 }
270
271 virtual ~BinTree() {
272 this->removeAll();
273 }
274
275 virtual const BinNode * root() const { return (const BinNode *) this->_root; }
276
285 void setCompareCallback(int (* cb) (T a, T b)) {
286 this->_compare = cb;
287 }
288
292 int insert(T obj) {
293 BinNode * newNode = (BinNode *) this->createNode();
294 newNode->_obj = obj;
295
296 if (this->root()) {
297 return this->insert(newNode, this->root());
298 } else {
299 newNode->_location = this->rootAddr();
300 this->setRoot(newNode);
301 this->_count++;
302 return 0;
303 }
304 }
305
306 S count() const { return this->_count; }
307
311 bool contains(T obj) {
312 return this->getNodeForObject(obj, this->root()) != NULL;
313 }
314
320 virtual void print() {
321 std::cout << std::endl;
322 this->print(this->root());
323 std::cout << std::endl;
324 }
325
326 // Returns object from the right most leaf
327 T max() const {
328 const BinNode * node = this->maxNode(this->root());
329 return node ? node->_obj : 0;
330 }
331
332 // Returns object from the left most leaf
333 T min() const {
334 const BinNode * node = this->minNode(this->root());
335 return node ? node->_obj : 0;
336 }
337
338 virtual const BinNode * minNode() const {
339 return this->minNode(this->root());
340 }
341
342 virtual const BinNode * maxNode() const {
343 return this->maxNode(this->root());
344 }
345
349 virtual int remove(T obj) {
350 BinNode * node = this->getNodeForObject(obj, this->root());
351 if (node) return this->deleteNode(node);
352 else return 1;
353 }
354
358 virtual int deleteNode(BinNode * node) {
359 int result = this->removeNode(node); // we do not need to know who replaced node
360
361 // Delete node
362 Delete(node);
363 if (result == 0) {
364 this->_count--;
365 }
366
367 return result;
368 }
369
373 int removeAll() {
374 int result = this->removeAll(this->root());
375 if (result == 0) this->_root = NULL;
376 return result;
377 }
378
384 int leafValues(List<T> * list) {
385 List<const BinNode *> leafNodes;
386 int result = this->locateLeafNodes(&leafNodes, this->root());
387
388 if (result == 0) {
389 typename List<const BinNode *>::Node * listNode = leafNodes.first();
390 do {
391 list->add(listNode->object()->_obj);
392 } while ((listNode = listNode->next()));
393 }
394
395 return result;
396 }
397
405 virtual int createIterator(Iterator ** itr) {
406 int result = 0;
407 if (!itr) return 9;
408 else {
409 *itr = new Iterator();
410
411 result = (*itr)->setCurrent(this->root());
412 }
413 return result;
414 }
415
424 virtual const BinNode * getNodeForObject(T obj) {
425 return this->getNodeForObject(obj, this->root());
426 }
427
438 int runCompare(T a, T b) const {
439 if (this->_compare) return this->_compare(a, b);
440 else {
441 if (a == b) return 0;
442 else if (a < b) return -1;
443 else if (a > b) return 1;
444 else return ~0;
445 }
446 }
447
448protected:
449
459 if (!node) return NULL;
460
461 int cmp = this->runCompare(node->_obj, obj);
462 if (cmp < 0) {
463 return this->getNodeForObject(obj, node->_right);
464 } else if (cmp > 0) {
465 return this->getNodeForObject(obj, node->_left);
466 } else {
467 return node;
468 }
469 return NULL;
470 }
471
473 BinNode ** rootAddr() { return (BinNode **) &this->_root; }
474 void setRoot(BinNode * node) { this->_root = node; }
475
476 // Derived classes can override
477 virtual BinNode * root() { return (BinNode *) this->_root; }
478
483
490 virtual void * createNode() {
491 return new BinNode;
492 }
493
494 BinNode ** getNodeLocation(const BinNode * node) { return node->_location; }
495 void setNodeLocation(BinNode * node, BinNode ** location) { node->_location = location; }
496
497 BinNode * getNodeParent(const BinNode * node) { return node->_parent; }
498 void setNodeParent(BinNode * node, BinNode * parent) { node->_parent = parent; }
499
508 virtual int insert(BinNode * newNode, BinNode * parent) {
509 BinNode ** newLocation = NULL;
510
511 if (!newNode) return 1;
512 else if (!parent) return 2;
513 else {
514 int cmp = this->runCompare(newNode->_obj, parent->_obj);
515 if (cmp > 0) {
516 newLocation = &parent->_right;
517 } else {
518 newLocation = &parent->_left;
519 }
520 }
521
522 // Continue traversing
523 if (!this->canNewNodeTakeNewLocation(newLocation)) return this->insert(newNode, *newLocation);
524 else {
525 newNode->_parent = parent;
526 //newNode->_location = newLocation;
527 this->setNodeLocation(newNode, newLocation);
528 *newLocation = newNode;
529
530 this->_count++;
531 }
532
533 return 0;
534 }
535
543 virtual bool canNewNodeTakeNewLocation(BinNode ** newLocation) {
544 return *newLocation == NULL;
545 }
546
553 int result = 0;
554 BinNode * rep = NULL;
555
556 if (node->childCount() != 1) {
557 result = 3;
558 }
559
560 if (result == 0) {
561 if (node->left()) {
562 rep = node->left();
563 node->setLeft(NULL);
564 } else if (node->right()) {
565 rep = node->right();
566 node->setRight(NULL);
567 } else {
568 result = 2;
569 }
570 }
571
572 // We do not need to worry about exchanging children
573 // since node only has 1 child
574 if (result == 0) {
575 // result = node->replaceWithNode(rep);
576 result = this->replaceNodeWithNode(node, rep);
577 }
578
579 return result;
580 }
581
589 virtual int replaceNodeWithNode(BinNode * node, BinNode * replacement) {
590 int result = 0;
591
592 // Make parent forget about replacement node
593 if (replacement) {
594 if (replacement->_parent) {
595 switch (replacement->childType()) {
596 case -1:
597 replacement->_parent->setLeft(NULL);
598 break;
599 case 1:
600 replacement->_parent->setRight(NULL);
601 break;
602 default:
603 break;
604 }
605 }
606 }
607
608 if (node->isRoot()) {
609 *node->_location = replacement;
610 if (replacement) {
611 replacement->_location = node->_location;
612 replacement->_parent = NULL;
613 }
614 } else {
615 switch (node->childType()) {
616 case -1:
617 node->_parent->setLeft(replacement);
618 break;
619 case 1:
620 node->_parent->setRight(replacement);
621 break;
622 default:
623 result = 2;
624 break;
625 }
626 }
627
628 if (result == 0) {
629 node->_parent = NULL;
630 node->_location = NULL;
631 }
632
633 return result;
634 }
635
639 int removeNode(BinNode * node) {
640 int result = 0;
641 unsigned char childCount = 0;
642
643 if (node == NULL) {
644 result = 1;
645 } else {
646 childCount = node->childCount();
647 }
648
649 if (result == 0) {
650 if (childCount == 0) {
651 // Right is null anyways
652 result = this->replaceNodeWithNode(node, node->left());
653 } else if (childCount == 1) {
654 result = this->replaceNodeWithTheOnlyChild(node);
655
656 // replaces with the successor
657 } else {
658 // Find the replacement for node
659 // should be a leaf
660 BinNode * max = (BinNode *) this->maxNode(node->left());
661
662 // repNode will be used to put max node's data in
663 // then we will put repNode in node
664 BinNode * repNode = node->clone();
665
666 // give max data to repNode
667 repNode->_obj = max->_obj;
668
669 // We must call our replace node
670 //
671 // It is known that RBTree does some color changes
672 // result = node->BinNode::replaceWithNode(repNode);
673 result = this->BinTree<T,S>::replaceNodeWithNode(node, repNode);
674
675 if (result == 0) {
676 if (node->left() != repNode) {
677 repNode->setLeft(node->left());
678 }
679 node->setLeft(NULL);
680
681 if (node->right() != repNode) {
682 repNode->setRight(node->right());
683 }
684 node->setRight(NULL);
685
686 result = this->removeNode(max);
687 }
688
689 if (result == 0) {
690 Delete(max);
691 }
692 }
693 }
694
695 return result;
696 }
697
698 virtual void print(BinNode * node) {
699 if (node->right()) this->print(node->right());
700
701 node->print();
702
703 if (node->left()) this->print(node->left());
704 }
705
707 virtual const BinNode * maxNode(const BinNode * node) const {
708 if (!node) return NULL;
709 else if (node->right()) return this->maxNode(node->right());
710 else return node;
711 }
712
714 virtual const BinNode * minNode(const BinNode * node) const {
715 if (!node) return NULL;
716 else if (node->left()) return this->minNode(node->left());
717 else return node;
718 }
719
720private:
721
725 int removeAll(BinNode * node) {
726 int result = 0;
727
728 // Just leave function if there is no node
729 if (!node) return 0;
730
731 if (node->left()) {
732 result = this->removeAll(node->left());
733 }
734
735 if (result == 0) {
736 if (node->right()) {
737 result = this->removeAll(node->right());
738 }
739 }
740
741 if (result == 0) {
742 Delete(node);
743 this->_count--;
744 }
745
746 return result;
747 }
748
752 virtual int locateLeafNodes(List<const BinNode *> * outList, const BinNode * node) {
753 int result = 0;
754
755 if (!node) return 1;
756 else if (node->childCount() > 0) {
757 if (node->left()) result = this->locateLeafNodes(outList, node->left());
758
759 if (result == 0)
760 if (node->right()) result = this->locateLeafNodes(outList, node->right());
761
762 return result;
763 } else {
764 result = outList->add(node);
765 return result;
766 }
767 }
768
774 int (* _compare) (T a1, T a2);
775
779 void * _root;
780};
781
782} // namespace BF
783
784#endif // BINTREE_HPP
785
Definition bintree.hpp:26
T _obj
Definition bintree.hpp:187
virtual void setLeft(BinNode *left)
Definition bintree.hpp:155
int level() const
Definition bintree.hpp:126
virtual BinNode * right()
Definition bintree.hpp:175
virtual const BinNode * left() const
Definition bintree.hpp:33
virtual unsigned char childCount() const
Definition bintree.hpp:117
virtual ~BinNode()
Definition bintree.hpp:77
char childType() const
Definition bintree.hpp:55
BinNode(T object)
Definition bintree.hpp:73
BinNode()
Definition bintree.hpp:65
virtual bool isLeaf() const
Definition bintree.hpp:38
virtual BinNode * sibling()
Definition bintree.hpp:104
BinNode ** leftAddr()
Definition bintree.hpp:173
const BinNode * parent() const
Definition bintree.hpp:35
virtual BinNode * clone()
Definition bintree.hpp:150
T object() const
Definition bintree.hpp:29
BinNode ** _location
Definition bintree.hpp:184
virtual BinNode * grandParent()
Definition bintree.hpp:86
bool isRoot() const
Definition bintree.hpp:43
virtual BinNode * left()
Definition bintree.hpp:172
virtual BinNode * pibling()
Definition bintree.hpp:92
virtual const BinNode * right() const
Definition bintree.hpp:34
BinNode * _parent
Definition bintree.hpp:179
BinNode ** rightAddr()
Definition bintree.hpp:176
virtual void setRight(BinNode *right)
Definition bintree.hpp:164
virtual void print() const
Definition bintree.hpp:130
Definition bintree.hpp:207
bool finished()
Definition bintree.hpp:239
Iterator()
Definition bintree.hpp:257
virtual int setCurrent(BinNode *node)
Definition bintree.hpp:246
virtual ~Iterator()
Definition bintree.hpp:211
Stack< BinNode * > _st
Definition bintree.hpp:262
T current()
Definition bintree.hpp:218
int next()
Definition bintree.hpp:225
Definition bintree.hpp:23
int insert(T obj)
Definition bintree.hpp:292
BinNode * getNodeParent(const BinNode *node)
Definition bintree.hpp:497
virtual ~BinTree()
Definition bintree.hpp:271
virtual const BinNode * minNode() const
Definition bintree.hpp:338
T max() const
Definition bintree.hpp:327
BinNode ** rootAddr()
Root accessors.
Definition bintree.hpp:473
virtual int insert(BinNode *newNode, BinNode *parent)
Definition bintree.hpp:508
virtual void * createNode()
Definition bintree.hpp:490
virtual int deleteNode(BinNode *node)
Definition bintree.hpp:358
BinTree()
Definition bintree.hpp:265
void setNodeParent(BinNode *node, BinNode *parent)
Definition bintree.hpp:498
virtual BinNode * root()
Definition bintree.hpp:477
virtual void print(BinNode *node)
Definition bintree.hpp:698
T min() const
Definition bintree.hpp:333
void setNodeLocation(BinNode *node, BinNode **location)
Definition bintree.hpp:495
bool contains(T obj)
Definition bintree.hpp:311
virtual bool canNewNodeTakeNewLocation(BinNode **newLocation)
Definition bintree.hpp:543
virtual const BinNode * maxNode(const BinNode *node) const
Returns the leaf node
Definition bintree.hpp:707
void setRoot(BinNode *node)
Definition bintree.hpp:474
virtual int remove(T obj)
Definition bintree.hpp:349
BinNode * getNodeForObject(T obj, BinNode *node)
Definition bintree.hpp:458
int runCompare(T a, T b) const
Definition bintree.hpp:438
S count() const
Definition bintree.hpp:306
S _count
Definition bintree.hpp:482
virtual void print()
Definition bintree.hpp:320
int removeNode(BinNode *node)
Definition bintree.hpp:639
virtual const BinNode * getNodeForObject(T obj)
Definition bintree.hpp:424
virtual const BinNode * maxNode() const
Definition bintree.hpp:342
virtual const BinNode * minNode(const BinNode *node) const
Returns the leaf node
Definition bintree.hpp:714
BinNode ** getNodeLocation(const BinNode *node)
Definition bintree.hpp:494
int removeAll()
Definition bintree.hpp:373
virtual const BinNode * root() const
Definition bintree.hpp:275
virtual int replaceNodeWithTheOnlyChild(BinNode *node)
Definition bintree.hpp:552
virtual int createIterator(Iterator **itr)
Definition bintree.hpp:405
int leafValues(List< T > *list)
Definition bintree.hpp:384
void setCompareCallback(int(*cb)(T a, T b))
Definition bintree.hpp:285
virtual int replaceNodeWithNode(BinNode *node, BinNode *replacement)
Definition bintree.hpp:589
Definition list.hpp:47
L object() const
Definition list.hpp:58
Node * next() const
Definition list.hpp:50
Definition list.hpp:41
int add(L obj)
Definition list.hpp:107
Node * first() const
Definition list.hpp:225
Definition object.hpp:21
Definition stack.hpp:23
#define Delete(x)
Definition delete.hpp:9
Definition array.hpp:18