Проблемы с реализацией итератора двусвязного списка

0

У меня возникают проблемы с простым классом списка Doubly-Linked.

Вот мой код:

/*
 * DLList.h
 *
 *  Created on: Nov 19, 2013
 *      Author: tyler
 */

#ifndef DLLIST_H_
#define DLLIST_H_
#include <iostream>
using namespace std;

template <typename T>
class DLList{
private:
struct DLLNode{
private:
    T data_;
    bool visited_;
    DLLNode* next_;
    DLLNode* prev_;
public:

    DLLNode(T data){
        this->data_ = data;
        visited_ = false;
        next_ = NULL;
        prev_ = NULL;
    }

    void setData(T data){
        this->data_ = data;
    }

    void visit(){
        visited_ = true;
    }

    void unvisit(){
        visited_ = false;
    }

    void setNext(DLLNode* next){
        this->next_ = next;
    }

    void setPrev(DLLNode* prev){
        this->prev_ = prev;
    }

    T& getData(){
        return data_;
    }

    bool getVisited(){
        return visited_;
    }

    DLLNode* getNext(){
        return next_;
    }

    DLLNode* getPrev(){
        return prev_;
    }
};

    DLLNode* head_;
    DLLNode* tail_;

public:
    DLList(){
        head_ = NULL;
        tail_ = NULL;
    }

    class DLLiterator{
    private:
        DLLNode* node;
    public:
        DLLiterator(){
            node = head_;
        }
        T& operator*(const DLLiterator& iter){
            return iter.node->getData();
        }
        DLLiterator& operator++(const DLLiterator& iter){
            if(node->getNext() != NULL)
                node = node->getNext;
            else
                node = NULL;
            return *this;
        }
    };   

    bool isEmpty(){
        return (head_ == NULL);
    }

    void addNodeEnd(T data){
        DLLNode* temp = new DLLNode(data);

        if(isEmpty()){
            head_ = temp;
            tail_ = temp;
        }
        else{
            DLLNode* curr;
            curr = tail_;
            curr->setNext(temp);
            temp->setPrev(curr);
            tail_ = temp;
        }
    } 

    bool contains(T data){
        for(DLLNode* start = head_; start != NULL; start = start->getNext()){
            if(start->getData() == data)
                return true;
        }
        return false;
    }

    void remove(T data){
        for(DLLNode* curr = head_; curr != NULL; curr = curr->getNext()){
            DLLNode* key = curr;
            if(curr->getData() == data){
                if(curr == head_){
                    head_ = key->getNext();
                    key->getNext()->setPrev(NULL);
                    delete key;
                }
                if(curr == tail_){
                    tail_ = key->getPrev();
                    key->getPrev()->setNext(NULL);
                    delete key;
                }
                else{
                    DLLNode* prev;
                DLLNode* next;
                    prev = key->getPrev();
                    next = key->getNext();
                    prev->setNext(next);
                    next->setPrev(prev);
                    delete key;
                }
            }
        }
    }

    void printList(){
        for(DLLNode* curr = head_; curr != NULL; curr = curr->getNext()){
            cout << curr->getData() << "\n";
        }
    }
};



#endif /* DLLIST_H_ */

Моя проблема в том, что я не знаю, как на самом деле использовать итератор в внешнем классе. Все остальное проверено и, кажется, работает нормально. Все равно нужно добавить простой деструктор, но сейчас я сосредоточен на итераторе. Любая помощь будет большой.

Я просто пытался:

DLLiterator iter;

но это явно неправильно...

EDIT: теперь это код operator++:

iterator operator++(){
    if(node_->getNext() != NULL)
        node_ = node_->getNext;
    else
        node_ = NULL;
    return *this;
}

но теперь он просит int как аргумент...?

  • 1
    Довольно большой кусок кода со слегка искаженным отступом, но если вы спрашиваете, как объявить итератор вашего связанного списка: DLList<int>::iterator iter; : DLList<int>::iterator iter;
  • 0
    Разве это не будет DLList<int>::DLLiterator iter ?
Показать ещё 2 комментария
Теги:
list
iterator

1 ответ

1

Вне класса вам придется использовать квалифицированное имя DLList<whatever>::DLLiterator. Вы можете видеть, что небольшая точка добавляет бородавку к вложенному имени, если вам не нравятся ваши имена, которые трудно читать: она лишь частично дублирует имя области. Я бы переименовал его в iterator.

Теперь ваша проблема заключается в том, что он пытается инициализировать себя с помощью члена списка head_, но у него нет доступа к списку для извлечения главы. Вероятно, вы захотите следовать примеру стандартных контейнеров и создать итератор через член списка:

iterator begin() {return iterator(head_);}

и соответственно измените конструктор итератора.

В С++ 11 это означает, что пользователям обычно не приходится записывать неприятное квалифицированное имя вообще; вы можете получить итератор с

auto it = list.begin();

Наконец, удалите аргументы из operator* итератора operator* и operator++. Поскольку они являются функциями-членами, их операнд передается неявно как this, а не явно как аргумент.

  • 0
    Это действительно помогло, но теперь оператор ++ запрашивает int в качестве аргумента ... см. Правку.
  • 0
    @tbgeorge: вы реализовали только предварительное увеличение, ++it . Если вы также хотите постинкремент, it++ , тогда вам также понадобится operator++(int) . (Пустой аргумент указывает, что это постинкремент, но не имеет никакого другого значения). Для этого потребуется скопировать итератор перед его увеличением и вернуть эту копию по значению.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню