【问题标题】:Iterator pointer does not reference the first element迭代器指针不引用第一个元素
【发布时间】:2018-03-30 14:08:13
【问题描述】:

我正在尝试实现一个可以在 c++ 中迭代的 LinkedList。

因此,我创建了一个 Iterator 类,这样取消引用 Iterator 将返回第一个元素。然而,这并没有奏效。然后当我实例化一个新的 int LinkedList 并尝试通过取消引用 begin() 的结果来访问第一个元素时,我不会检索列表的第一个元素,而是一个 10 位数字,例如“1453755360”

我的节点类只是由两个右/左节点指针和一个数据变量组成

链表类

template <typename T>
class LinkedList{

public:
    LinkedList(){
        count =(0);
        head =(nullptr);
        tail =(nullptr);
    }

    void push_head(T input){

        Node<T> newNode = Node<T>(input);
        newNode.left = nullptr;
        newNode.right = head;

        head = &newNode;
        count++;
    }

    T front(){
        T& data = (head->data);
        return data;
    }

    void push_tail(T input){

        Node<T> newNode = Node<T>(input);
        newNode.right = tail;
        newNode.left = nullptr;

        tail = &newNode;
        count++;
    }

    T back(){
        T& data = (tail->data);
        return data;
    }


    Iterator<T> begin(){
        Iterator<T> test = Iterator<T>(head);
        return test;
    }


private:
    int count;
    Node<T> *head;
    Node<T> *tail;

};

这是我测试代码的地方

    LinkedList<int> ll;

    ll.push_tail(7);
    ll.push_tail(9);

    if (*(ll.begin()) == 9) {
        cout << "pass" << endl;
    } else {
        cout << "returned : " << *(ll.begin()) << endl;
    }

【问题讨论】:

  • 使用你的链表的代码在哪里?
  • 这几乎可以肯定是一个错误
  • 这个Node&lt;T&gt; newNode = Node&lt;T&gt;(input);将在作用域结束时被销毁。
  • 我成功将元素推送到列表中,但我无法从迭代器中检索元素
  • 不,绝对不是。使用调试器自己看看。

标签: c++ linked-list iterator


【解决方案1】:

push_back() 实现要求如果 head 为空,则必须设置它,push_front 相对于 tail 也是如此。

【讨论】:

    【解决方案2】:

    您正在堆栈上分配节点对象,因此当它们超出范围时它们会自动销毁。您正在存储指向这些对象的指针,这会在对象被销毁时使指针悬空。您需要使用new 来分配堆上的节点。

    此外,push_front() 在列表为空时不会更新tail,并且在列表不为空时不会更新现有的head 以指向新节点。与push_back()类似。

    试试这样的:

    template <typename T>
    struct Node
    {
        T data;
        Node *left;
        Node *right;
    
        Node(const T &d = T(), Node *l = nullptr, Node *r = nullptr)
            : data(d), left(l), right(r) {}
    };
    
    template <typename T>
    class NodeIterator {
    public:
        typedef std::ptrdiff_t difference_type;
        typedef T value_type;
        typedef T* pointer;
        typedef T& reference;
        typedef std::bidirectional_iterator_tag iterator_category;
    
        NodeIterator(Node<T> *input = nullptr) : cur(input) {}
        NodeIterator(const NodeIterator &) = default;
        NodeIterator(NodeIterator &&) = default;
        ~NodeIterator() = default;
    
        NodeIterator& operator=(const NodeIterator &) = default;
        NodeIterator& operator=(NodeIterator &&) = default;
    
        reference operator*() {
            return cur->data;
        }
    
        NodeIterator& operator++ () {
            if (cur) cur = cur->right;
            return *this;
        }
    
        NodeIterator operator++ (int) {
            NodeIterator tmp(*this);
            if (cur) cur = cur->right;
            return tmp;
        }
    
        NodeIterator& operator-- () {
            if (cur) cur = cur->left;
            return *this;
        }
    
        NodeIterator operator-- (int) {
            NodeIterator tmp(*this);
            if (cur) cur = cur->left;
            return tmp;
        }
    
        bool operator==(const NodeIterator &rhs) const {
            return (rhs.cur == cur);
        }
    
        bool operator!=(const NodeIterator &rhs) const {
            return (rhs.cur != cur);
        }
    
    private:
        Node<T> *cur;
    };
    
    template <typename T>
    class LinkedList {
    public:
        typedef NodeIterator<T> iterator;
    
        LinkedList() : count(0), head(nullptr), tail(nullptr) {}
    
        ~LinkedList() {
            while (head) {
                Node<T> *tmp = head;
                head = head->right;
                delete tmp;
            }
        }
    
        void push_front(const T &input) {
            Node<T> *newNode = new Node<T>(input, nullptr, head);
    
            if (head) head->left = newNode;
            head = newNode;
    
            if (!tail) tail = newNode;
    
            ++count;
        }
    
        T& front() {
            return head->data;
        }
    
        void push_back(const T &input) { 
            Node<T> *newNode = new Node<T>(input, tail, nullptr);
    
            if (!head) head = newNode;
    
            if (tail) tail->right = newNode;
            tail = newNode;
    
            ++count;
        }
    
        T& back() {
            return tail->data;
        }
    
        iterator begin() {
            return iterator(head);
        }
    
        iterator end() {
            return iterator();
        }
    
    private:
        int count;
        Node<T> *head;
        Node<T> *tail;    
    };
    

    那么你可以这样做:

    LinkedList<int> ll;
    
    ll.push_back(7);
    ll.push_back(9);
    
    auto iter = ll.begin();
    if (*iter == 7) {
        cout << "pass" << endl;
    } else {
        cout << "returned : " << *iter << endl;
    }
    

    你现在甚至可以这样做:

    for (LinkedList<int>::iterator iter = ll.begin(), end = ll.end(); iter != end; ++iter) {
        cout << *iter << endl;
    }
    

    for (int i : ll) {
        cout << i << endl;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-23
      • 2014-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-28
      • 2018-12-15
      • 1970-01-01
      相关资源
      最近更新 更多