重载自定义迭代器的解引用运算符

时间:2013-12-01 04:12:47

标签: c++ iterator operator-overloading dereference

这是我第一次使用迭代器,因此可能存在重大错误。我试图使一个inorder迭代迭代器类与我的线程二进制搜索树一起工作。所以迭代器正在节点上工作。我只需要迭代器来遍历我的树,这样我就可以打印每个节点的所有值和频率。然而,我的解除引用似乎并没有起作用。这是给我带来麻烦的方法:

//-------------------------- inOrderTraverse ------------------------------------
template <typename T>
void ThreadedBST<T>::inOrderTraverse() {
    InorderIterator<T>* iter = new InorderIterator<T>(root);
    ++iter;

    while ((*iter) != NULL)
    {
        cout << (*iter)->getItem() << " " << (*iter)->getFrequency() << endl;
    }
}

特别是while循环会引发编译器错误。这是确切的错误:

错误C2678:二进制'!=':找不到哪个运算符带有'InorderIterator'类型的左手操作数

我认为取消引用会使节点退出,所以我实际上是在比较节点!= NULL,但这不是错误消息让我相信的。这是完整的Iterator类:

#ifndef INORDERITER_H
#define INORDERITER_H

#include <iostream>
#include "ThreadedBST.h"
using namespace std;

//---------------------------------------------------------------------------
// InorderIterator<T> class: 
//   -- 
//
// Assumptions:
//   -- <T> implements it's own comparable functionality
//---------------------------------------------------------------------------

template <typename T>
class InorderIterator {

public:
    InorderIterator(node<T> *); //constructor
    InorderIterator<T>& operator++();
    node<T>& operator*();
    const node<T>& operator*() const;

private:
    node<T>* begin;
    node<T>* curr;
    node<T>* prev;
    node<T>* temp;
};

template <typename T>
InorderIterator<T>::InorderIterator(node<T>* root) {
    begin = root;
    temp = NULL;

    while (begin->leftChild != NULL) {
        begin = begin->leftChild;
    }
}

template <typename T>
InorderIterator<T>& InorderIterator<T>::operator++() {
    if (temp == NULL)
        temp = begin;
    else if (rightChildThread) {
        prev = temp;
        temp = temp->rightChild;
    }
    else {
        prev = temp;
        temp = temp->rightChild;

        while (!temp->rightChildThread && (temp->leftChild->getItem() != prev->getItem())) {
            temp = temp->leftChild;
        }
    }

    curr = temp;
    return *this;
}

template <typename T>
node<T>& InorderIterator<T>::operator*() {
    return *curr;
}

template <typename T>
const node<T>& InorderIterator<T>::operator*() const {
    return *curr;
}

#endif

如果节点类与任何原因相关,那么这是节点类:

#ifndef NODE_H
#define NODE_H

#include <iostream>
using namespace std;

//---------------------------------------------------------------------------
// node<T> class: 
//   -- 
//
// Assumptions:
//   -- <T> implements it's own comparable functionality
//---------------------------------------------------------------------------

template <typename T>
class node {

public:
    node<T>* leftChild;
    node<T>* rightChild;
    bool leftChildThread;
    bool rightChildThread;
    node(T value); //constructor
    node(T value, node<T>*, node<T>*, bool, bool); //secondary constructor
    node(const node<T>&); //copy constructor
    void decrementFrequency(); //decrements by 1 the frequency
    void incrementFrequency(); //increments by 1 the frequency
    int getFrequency(); //returns the frequency
    T getItem(); //returns the item

private:
    T item;
    int frequency;
};

//-------------------------- Constructor ------------------------------------
template <typename T>
node<T>::node(T value) {
    item = value;
    frequency = 1;

}

//-------------------------- Secondary Constructor ------------------------------------
template <typename T>
node<T>::node(T value, node<T>* left, node<T>* right, bool leftThread, bool rightThread) {
    item = value;
    frequency = 1;
    leftChild = left;
    rightChild = right;
    leftChildThread = leftThread;
    rightChildThread = rightThread;
}

//-------------------------- Copy ------------------------------------
template <typename T>
node<T>::node(const node<T>& copyThis) {
    item = copyThis.value;
    frequency = copyThis.frequency;
}

//-------------------------- decrementFrequency ------------------------------------
template <typename T>
void node<T>::decrementFrequency() {
    frequency--;
}

//-------------------------- incrementFrequency ------------------------------------
template <typename T>
void node<T>::incrementFrequency() {
    frequency++;
}

//-------------------------- getFrequency ------------------------------------
template <typename T>
int node<T>::getFrequency() {
    return frequency;
}

//-------------------------- getItem ------------------------------------
template <typename T>
T node<T>::getItem() {
    return item;
}

#endif

1 个答案:

答案 0 :(得分:4)

  class const_iterator {
    public:
        Node *current;

        const_iterator (Node *n) : current{n}
        {
            /* the body can remain blank, the initialization is carried
             * the the constructor init list above
             */
        }

        /* copy assignment */
        const_iterator operator= (const const_iterator& rhs) {
            this->current = rhs.current;
            return *this;
        }

        bool operator == (const const_iterator& rhs) const {
            return this->current == rhs.current;
        }
        bool operator != (const const_iterator& rhs) const {
            return this->current != rhs.current;
        }

        /* Update the current pointer to advance to the node
         * with the next larger value
         */
        const_iterator& operator++ () {
            /*first step is to go left as far as possible(taken care of by begin())
             once you go as left as possible, go right one step at a time*/
            if(current->right != nullptr){
                current = current->right;
                //every step, go left again as far as possible
                while(current->left != nullptr){
                    current = current->left;
                }
            }else{
                bool upFromLeft = false;
                bool upFromRight = false;
                while(upFromLeft == false && upFromRight == false){
                    //if you have gone all the way up from the right
                    if(current->parent == nullptr){
                        upFromRight = true;
                        current = current->parent;
                        return *this;
                    }
                    //if you have gone all the way back up left
                    if(current->parent->left == current){
                        upFromLeft = true;
                        current = current->parent;
                        return *this;
                    }
                    current = current->parent;
                }
            }
            return *this;
        }

        Z& operator *() const {
            return current->data;
        }
    };

将这些函数添加到树中,以便将begin()和end()与迭代器一起使用

        const const_iterator begin() const {
        if(rootPtr == nullptr){
            return nullptr;
        }
        Node* temp = rootPtr;
        while(temp->left != nullptr){
            temp = temp->left;
        }
        return const_iterator(temp);
    }

    /* For the "end" marker
     * we will use an iterator initialized to nil */
    const const_iterator end() const {
        return const_iterator(nullptr);
    }

这是我在C ++中编写的有序迭代器的一个例子......

这个迭代器假设BST中的每个节点都有一个指向父节点的指针,这是我在节点类中看不到的。但是,我不确定它是否有可能在没有父指针的情况下完成inorder遍历。

简而言之,如果您向节点添加父指针并在每次执行节点插入或删除时更新父指针,此示例将起作用