简体   繁体   中英

Decrementing iterator from end() iterator in binary search tree

In a binary search tree, the end() member function shall simply return iterator(nullptr) , right? But the node nullptr contains no information about its left , right , and parent data. So how do we decrement an iterator from end() ? The following is what I have so far (defined in the iterator<T> class). My iterator<T> class has node<T>* ptr as its only data member, and my node<T> class has members T value; node *left, *right, *parent; T value; node *left, *right, *parent; .

    iterator& operator--() {
//      if (!ptr) what to do???
        if (ptr->left)
            ptr = node<T>::max_node(ptr->left);
        else {
            node<T>* previous = ptr;
            ptr = ptr->parent;
            while (ptr && ptr->left == previous) {
                previous = ptr;
                ptr = ptr->parent;
            }
        }
        return *this;
    }

Instead of end() being iterator(nullptr) make it iterator(&anchor), where anchor is the member of the containing tree that is used to hold the root beginning and final node pointers. And then to decrement you simply step back to the preceding node (the opposite action to increment).

It does require somewhat more work than simply holding a root node pointer but it also allows begin() and end() to be O(1) operations.

If you want your iterator to be a bidirectional iterator you'll need to provide the necessary information to find the last node of the tree in the iterator returned by end() . To avoid dealing with a special case just to decrement the end() iterator you could use a “secret” node which uses its left pointer to point at the root of the tree. This way the end() iterator would simply be a pointer to this secret node: with this approach there is no need for any special treatment in increment, decrement, or comparison.

Since it is generally undesirable to store a node value in the root the usual implementation splits the nodes into a NodeBase holding only the pointer needed for navigation and a NodeValue deriving from the NodeBase and adding the node's value. The root uses a NodeBase member and the iterator type a NodeBase* : for the navigation only the pointers are needed. Since only valid iterators are allowed to be dereferenced a static_cast<NodeValue*>(n) can be used to obtain the NodeValue when accessing the node's value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM