当前位置: 首页 > 知识库问答 >
问题:

迭代器指针不引用第一个元素

丌官哲彦
2023-03-14

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

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

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

linkedlist类

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;
    }

共有2个答案

郎嘉树
2023-03-14

您正在堆栈上分配节点对象,因此当它们超出范围时会自动销毁。您正在存储指向这些对象的指针,当对象被销毁时,指针会悬空。您需要使用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;
}
穆建元
2023-03-14

push_back()实现要求,如果head为null,则必须将其设置为null,对于尾部push_front也是如此。

 类似资料:
  • 本文向大家介绍请你来说一下STL中迭代器的作用,有指针为何还要迭代器?相关面试题,主要包含被问及请你来说一下STL中迭代器的作用,有指针为何还要迭代器?时的应答技巧和注意事项,需要的朋友参考一下 1、迭代器 Iterator(迭代器)模式又称Cursor(游标)模式,用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。或者这样说可能更容易理解:Iterator模式是运用

  • 我将获取一个用户列表作为数组,对数据进行分页,并以表格的形式显示在视图中。 为了迭代数组,我使用 foreach 循环。但是我的前循环迭代不起作用。 这是一个示例数组,当我执行< code>print_r()时,我有< code>id、< code>email和< code>full_name字段,我想在视图中显示它们 这是我迭代数组的视图部分。结果存储在< code>$userList中。这个数

  • 我有一个Firebase数据库,在一个特定的节点级别上有日期,每个日期都有键值对,其值为一定的数字。现在我需要找到最近两天常见的数字。

  • 我想在HashMap中搜索重复项。目前这是我的HashMap:

  • 问题内容: 我有一个在HashMap上使用的迭代器,并且保存并加载了该迭代器。有没有办法用迭代器在HashMap中获取上一个密钥?(java.util.Iterator) 更新资料 我将其另存为Red5连接中的属性,然后将其重新加载以在我停止的地方继续工作。 另一个更新 我正在遍历HashMap的键集 问题答案: 正如其他人指出的那样,它并不直接,但是例如,如果您需要访问一个先前的元素,则可以轻松