微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 LinkedList 类中实现迭代器类

如何解决如何在 LinkedList 类中实现迭代器类

刚接触 C++,我在 LinkedList 中实现 Iterator 类时遇到问题。我在 LinkedList 类的私有部分定义了一个 Iterator 类,如下所示:

cs_linked_list.h

 #ifndef LINKED_LIST_H_
 #define LINKED_LIST_H_

 #include <initializer_list>
 #include <iostream>

 namespace cs {
template <typename T>
class LinkedList {
    struct Node;  // forward declaration for our private Node type

public:
    /**Constructs an empty list.**/
    LinkedList(){
        head_ = nullptr;
    }
    /**
    * @brief Constructs a list from a range.
    *
    */
    template <class InputIterator>
    LinkedList(InputIterator first,InputIterator last) {
        for (; first != last; ++first) this->push_back(*first);
    }

    /** Constructs a list with a copy of each of the elements in `init_list`,in the same order. */
    LinkedList(std::initializer_list<T> init_list) {
        this->operator=(init_list);  // call initializer list assignment
    }

    /**Constructs a container with a copy of each of the elements in another,in the same order**/
    LinkedList(const LinkedList<T>& another){
        //Todo
        this->operator=(another);


    }
    /** Destroys each of the contained elements,and deallocates all memory allocated by this list. */
    ~LinkedList() {
        while (this->head_) {
           Node* old_head = this->head_;
           this->head_ = old_head->next;
           delete old_head;
         }
    }
    /**Returns the number of elements in this list.Node *head**/
     size_t size() const{ //DONE
        //Todo
        Node *temp = head_;
        size_t len = 0;
        while (temp != nullptr){
            len++;
            temp = temp->next;
        }
        return len;
    }
    /**Returns whether the list container is empty (that is,whether its size is 0). **/
    bool empty() const{ //DONE
        if(size_ == 0){
            return true;
        } else{
            return false;
        }
    }
    /** Appends a copy of `val` to this list. */
    void push_back(const T& val) {
        Node* new_node = new Node{val};
        if (this->size_ == 0) {
            this->head_ = this->tail_ = new_node;
        } else {
            this->tail_->next = new_node;
            new_node->prev = this->tail_;
            this->tail_ = new_node;
        }
        ++this->size_;
    }
    /**  Prepends a copy of `val` to this list. */
    void push_front(const T& val) {
        Node* new_node = new Node{val};  
        if (this->size_ == 0) {
            this->head_ = this->tail_ = new_node;
        } else {
            new_node->next = this->head_;
            this->head_->prev = new_node;
            this->head_ = new_node;
        }
        ++this->size_;
    }

    /**Returns a reference to the value in the first element in this list.**/
    T& front() const{
        return head_->data;
    }

    /**Returns a reference to the value in the last element in this list. **/
    T& back() const{
        return tail_->data;
    }

    /**Deletes the first value in this list. **/
    void pop_front(){
        Node *temp = head_;
        if(empty()){
            return;
        }
        if(temp == tail_){
            return;
        }
        head_ = head_->next;
        if (head_ != nullptr) {
            head_->prev = nullptr;
        } else {
            tail_ = nullptr;
        }
        delete temp;

    }

    /**Deletes the last value in this list**/
    void pop_back(){
        if(empty()){
            return;
        }
        if(head_ == tail_){
            return;
        }
        Node *temp = head_;
        while(temp->next->next != nullptr){
            temp = temp->next;
        }
        tail_ = temp;
        delete tail_->next;
        tail_->next = nullptr;
        size_--;

    }

    /**resizes the list so that it contains n elements.**/
    void resize(std::size_t n){
        //Todo
        for (size_t i = 0; i < n; i++){
            push_back('\0');
        }

    }

    /**resizes the list so that it contains n elements**/
    void resize(std::size_t n,const T &fill_value){
        //Todo
        for (size_t i = 0; i < n; i++) {
            push_back(fill_value);
        }
    }
    /**Removes from the container all the elements that compare equal to val. **/
    void remove(const T &val){
        //Todo
        Node *p1 = head_;
        Node *p2 = nullptr;
        if(p1 != nullptr && p1->data == val){
            head_ = p1->next;
            delete p1;
        } else {
            while (p1 != nullptr && p1->data != val){
                p2 = p1;
                p1 = p1->next;
            }
            if (p1 == nullptr) {
                return;
            }
            p2->next = p1->next;
            delete p1;
        }
    }

    /**Removes duplicate values from this list**/
    void unique(){
        //Todo
        Node *temp = head_;
        while (temp != nullptr && temp->next != nullptr) {
            Node *temp2 = temp;
            while (temp2->next != nullptr) {
                if (temp->data == temp2->next->data) {
                    Node *temp3 = temp2->next;
                    temp2->next = temp2->next->next;
                    delete temp3;
                } else {
                    temp2 = temp2->next;
                }
            }
            temp = temp->next;
        }
    }
    /**Deletes all values in this list.**/
    void clear(){
        //Todo
        while (head_ != nullptr){
            Node *temp = head_;
            head_ = head_->next;
            delete temp;
        }
        tail_ = nullptr;
        size_ = 0;
    }

    /**Reverses the order of the elements in this list.**/
    void reverse(){
        //Todo
        Node *p1 = head_;
        Node *p2 = nullptr;
        while (p1 != nullptr) {
            Node *temp = p1->next;
            p1->next = p2;
            p2 = p1;
            p1 = temp;
        }
        head_ = p2;
    }
    /** Replaces the contents of this list with a copy of each element in `init_list`. */
    LinkedList& operator=(std::initializer_list<T> init_list) {
        this->size_ = 0;
        for (auto&& val : init_list)
            this->push_back(val);
        return *this;
    }

    /**Replaces the contents of this list with a copy of each element in another,in the same order.**/
     LinkedList& operator=(const LinkedList& another){
         //Todo
        if (this != &another) {
            this->clear();
            Node *temp = another.head_;
            this->size_ = 0;
            while (temp) {
                this->push_back(temp->data);
                temp = temp->next;
            }
        }
        return *this;
    }
    /**Compares this list with another for equality.**/
    bool operator==(const LinkedList &another){ //DONE
        //Todo
        auto comp = head_;
        auto comp2 = another.head_;
        while(comp != nullptr){
            if(comp != comp2){
                return false;
            }
            comp = comp->next;
            comp2 = comp2->next;
        }
        return true;

    }

    /**Compares this list with another for inequality. **/
    bool operator!=(const LinkedList &another){ //DONE
        //Todo
        auto comp = head_;
        auto comp2 = another.head_;
        while(comp != nullptr){
            if(comp != comp2){
                return true;
            }
            comp = comp->next;
            comp2 = comp2->next;
        }
        return false;

    }
    /** Inserts this list into an ostream,with the format `[element1,element2,element3,...]` */
    friend std::ostream& operator<<(std::ostream& out,const LinkedList& list) {
        out << '[';
        for (Node* cur = list.head_; cur; cur = cur->next) {
            out << cur->data;
            if (cur->next)
                out << ",";
        }
        out << ']';
        return out;
    }private:
    struct Node {
        T data;
        Node* next = nullptr;
        Node* prev = nullptr;
    };
    Node* head_ = nullptr;
    Node* tail_ = nullptr;
    std::size_t size_ = 0;
    class Iterator {
    public:
        using iterator_category = std::bidirectional_iterator_tag;
        using value_type = T;
        using difference_type = int;
        using pointer = T*;
        using reference = T&;
        // Default constructor
        Iterator() {
            //Todo
            n = nullptr;
        }
        // copy constructor
        Iterator(const Iterator& other) {
            //Todo
            this->operator=(other);
        }
        //Destructor if needed
        ~Iterator() {
            //Todo
            while (this->list.head_){
                Node *old_head = this->list.head_;
                this->list.head_ = old_head->next;
                delete old_head;
            }
        }
        // copy assign
        Iterator& operator=(const Iterator& that) {
            //Todo
            if(this != &that){
                this->list.clear();
                Node *temp = that.list.head_;
                this->list.size_ = 0;
                while (temp){
                    this->list.push_back(temp->data);
                    temp = temp->next;
                }
            }
            return *this;

        }
        // Prefix increment
        Iterator& operator++() {
            //Todo
            this->n = this->n->next;
            return *this;
        }
        // Postfix increment
        Iterator operator++(int) {
            Iterator tmp(*this);
            this->operator++();
            return tmp;
        }
        // Prefix decrement
        Iterator& operator--() {
            //Todo
            this->n = this->n->prev;
            return *this;
        }
        // Postfix decrement
        Iterator operator--(int) {
            Iterator tmp(*this);
            this->operator--();
            return tmp;
        }
        // Inequality
        bool operator!=(Iterator that) const {
            return !(this->operator==(that));
        }
        // Equality
        bool operator==(Iterator that) const {
            //Todo
            auto temp = list.head_;
            auto temp2 = that.list.head_;
            while(temp != nullptr){
                if(*temp != *temp2){
                    return false;
                }
                temp = temp->next;
                temp2 = temp2->next;
            }
            return true;
        }
        // lvalue dereference
        T& operator*() const {
            //Todo
            return this->n->data;

        }
        // referring
        Iterator* operator->() const {
            return this;
        }
        Iterator begin(){
        //Todo
        return Iterator(list.head_->next);
        }
        Iterator end(){
        //Todo
        return Iterator(list.tail_);
        }

    private:
        Node *n;
        LinkedList<T> list;
    };
};

}  // namespace cs

#endif  // LINKED_LIST_H_

主要内容

#include "cs_linked_list.h"
#include <iostream>

int main() {
/***TESTING***/
cs::LinkedList<int> list;
// Add few items to the end of LinkedList
list.push_back(1);
list.push_back(2);
list.push_back(3);
std::cout << "Traversing LinkedList through Iterator" << std::endl;
for ( cs::LinkedList<int>::Iterator iter = list.begin();iter != list.end(); iter++) {
    std::cout << *iter << " ";

}
std::cout << std::endl;
return 0;
}

由于我的 Iterator 类是私有的,我似乎无法实现我的 Begin() 和 End() 函数。我应该公开它还是我错过了关键的一步。说明说在我的 LinkedList 类的私有部分定义一个 Iterator 类。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。