I'm new to c++ and I face some problems implementing the iterator on the template class Tree (structure of the code includes the canonical classes (Node,Tree,Iterator).
Fwd iterator is not working properly when tested (with the following extract) in the main:
//expected result: 16 | 20 | 61 | 65 | 71 | 76 | 81 | 85 | 90 | 93 | 101 |
auto it{rbt.begin()};
auto end{rbt.end()};
std::cout << *it << std::endl; // works fine=16
std::cout << *end // works fine = set to nullptr, returns 0
while(it!=end) {
std::cout << *it << std::endl;
it++;
}
//getting alternatively the following errors when trying different solutions:
//A- just |16| and then iterator stops
//B- overflowing with |16|16|16|16|16|16|16|16|16|16|16 never stopping
//C- overflowing with |16|0|16|0|16|0|16|0|16|0|16|0|16 never stopping
//D- segmentation fault core (dump)
I suppose this is due to the way the Tree is created, in particular the fact of leaving some helper "NIL"s (pointers to initialized but empty nodes) alive in memory. They are necessary for other Tree methods (like insert/delete), but for what is my understanding are then interfering with the correct functioning of the iterator which, instead of simply skipping them, gets stuck somewhere. I have tried to do that myself changing the main condition of the operator++(): from
if(current_node->right!=nullptr)
to
if(current_node->right!=NIL)
within the iterator class, but I get the "invalid use of non-static data member ‘RBTree::NIL’" error, and I do not know what to do to fix it, letting the NIL private member of Tree be visible inside Iterator as well. Here the more details on the classes and a link with the complete code:
template <class T, class CMP>>
class Tree {
public:
typedef T node_type;
typedef _Node<node_type> Node; ///< type of template tree node.
typedef Node *NodePtr; ///< type of pointer to template tree node.
class const_iterator;
private:
NodePtr root;
NodePtr NIL; ///< empty node, probable cause of the problem
Extract from the Iterator class:
template <class T, class CMP>
class RBTree<T, CMP>::const_iterator {
friend class RBTree;
private:
NodePtr current_node;
public:
const_iterator& operator++() { // this is the method causing issues
if(current_node->right!=nullptr) {
current_node = current_node->right->leftmost();
}
else {
current_node = current_node->rightmost();
}
return *this;
}
and finally the Node class:
template <class T>
class _Node {
public:
friend class const_iterator; //allows const_iterator using leftmost() and rightmost()
T data; //key
Color color; //color
_Node *left, *right, *parent; ///< pointers to parent, left and right children.
//Default Constructor of a RBTree's node.
_Node() {}
_Node(T key, Color clr=BLACK, _Node *parent=nullptr) : data{key}, color{clr}, left{nullptr}, right{nullptr}, parent{parent} {}
~_Node() noexcept {}
_Node* leftmost() noexcept {
if(left!=nullptr) {
return left->leftmost();
}
return this;
}
_Node* rightmost() const {
if(parent!=nullptr) {
if(parent->right==this) {
return parent->rightmost();
}
}
return parent;
}
Thank you in advance if you would like to help me understand and improve my code: I know there may be many other errors around so please, any advice is very welcome and a way for me to grow my skills.