【问题标题】:C++ Nested Iterator Class (In Linked List Class) Insert_After FunctionC++ 嵌套迭代器类(在链表类中)Insert_After 函数
【发布时间】:2019-11-06 19:12:06
【问题描述】:

我有一个嵌套在 LinkedList 类中的迭代器类。我的问题是如何使用迭代器制作 insert_after 函数。其余代码仅供参考,但我尝试使用的功能在最后。

Insert_After 获取一个位置并在其后插入一个值。

template <typename T>
class LinkedList : public LinkedListInterface<T> {
private:
    struct Node {

    T data; // data can be any type
    Node* next; // points to the next Node in the list

    Node(const T& d, Node* n) : data(d), next(n) {}
};
Node* head; // Is a pointer

class Iterator
{
private:
    Node* iNode;
public:
    Iterator(Node* head) : iNode(head){ }
    ~Iterator() {}
    bool operator!=(const Iterator& rhs) const { return iNode != rhs.iNode; }
    Iterator& operator++() { iNode = iNode->next; return *this; }
    T& operator*() const { return iNode->data; }
};

/** Return iterator pointing to the first value in linked list */
Iterator begin(void) {
    return LinkedList<T>::Iterator(head); 
}

/** Return iterator pointing to something not in linked list */
Iterator end(void) {
    return LinkedList<T>::Iterator(NULL); 
}

/** Return iterator pointing found value in linked list */
Iterator find(Iterator first, Iterator last, const T& value) {
    Iterator current = first;
    bool found = false;
    while (current != last) {
        if (*current == value) {
            return current;
        }

        ++current;
    }

    return last;
}

Iterator insert_after(Iterator position, const T& value)
{
    // Need help here
}

到目前为止,我的尝试导致了一些错误。

Iterator insert_after(Iterator position, const T& value)
{
    // Need to insert after position
    Iterator previous = position;
    ++position;
    Node* newNode = new Node(value, position);
    previous->next = newNode;

}

我得到的错误是 Error C2664 'function' : cannot convert argument n from 'type1' to 'type2' for the line

Node* newNode = new Node(value, position);

编译器错误 C2819 类型 'type' 没有用于行的重载成员 'operator ->'

previous->next = newNode;

我了解这些错误,但我不确定如何解决它们。

【问题讨论】:

标签: c++ insert iterator


【解决方案1】:

我认为对编译器错误的简短回答是,您可能应该传递 NodeNode* 作为第二个参数,而不是迭代器。 previous 也是一个迭代器,因此没有 next 调用。

下面是关于一般修复相关功能的长答案:
该函数中有很多 [not] 发生,这也让我想知道链表类的其余部分。我只看过这个功能,因为它是你声称给你带来麻烦的那个。

主观思考我通常讨厌在我的类函数中使用迭代器。尽可能直接处理节点。迭代器模式存在于容器的通用遍历中,无论它们是如何布局的,这种抽象使得在类中处理它很痛苦。

Iterator insert_after(Iterator position, const T& value)
{
    // Need to insert after position
    Iterator previous = position;
    ++position;
    Node* newNode = new Node(value, position);
    previous->next = newNode;

}

就目前而言,如果position 位于除最后一个元素之外的任何位置,您将破坏您的列表并泄漏内存。这是因为您从不检查position 之后的内容。第一个错误导致第二个错误。 newNode-&gt;next 永远不会被设置。也许它默认构造为nullptr,这很好。但是,如果我要插入到列表的中间,我需要将 newNode 连接到最初出现在 position 之后的任何内容。

您需要考虑的另一个问题是“如果在空列表上调用它会怎样?”你的begin() 函数能处理这个吗?应该扔吗?

Iterator insert_after(Iterator position, const T& value)
{
    Node* pos = position.iNode;

    if (!pos) {  // assumes an empty list if this is true
        // Correctly build first Node of your list and get everything assigned
        // that you can
        // return the new iterator;

        // or just throw
    }

    if (!pos->next) {  // position at end of list if true
        pos->next = new Node(value, position);  // Is that second argument
                                                // supposed to be an iterator?
        return Iterator(pos->next);
    } else {
        // Some of this is probably redundant depending on how you are actually
        // building Nodes, but the gist is it's important to ensure the list is
        // not broken; connecting tmp before changing existing nodes helps the
        // list stay intact for as long as possible
        Node* tmp = new Node(value, position);
        tmp->next = pos->next;
        pos->next = tmp;

        return Iterator(tmp);
    }    

双向链表对学生来说乍一看似乎并不吸引人,但它使某些操作(例如从列表中间擦除)变得容易得多。是的,你有一个额外的指针要处理,但这也使得丢失节点变得更加困难。以及双向迭代。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    • 1970-01-01
    相关资源
    最近更新 更多