【问题标题】:Implementing begin() and end() for doubly linked list为双向链表实现 begin() 和 end()
【发布时间】:2014-03-18 14:44:05
【问题描述】:

我编写了自己的容器类,其原始内部数据结构是std::list。然后我需要创建自己的双向链表。我现在已经实现了我自己的双向链表以及我自己的链表迭代器,但我在让它表现得像 std::list 时遇到了问题,尤其是在 begin()end() 时。

据我了解,begin() 应该指向第一个节点,end() 应该指向最后一个元素之后的一个元素。我需要确保当我调用end() 时,我可以递减回有效的最后一个元素。我还需要确保我可以进行正常的遍历,例如...

while (beg != end ) { do something; beg++; }

基本上我的链表只使用包含数据元素、指向前一个节点的指针和指向下一个节点的指针的节点。

当我第一次尝试实现我的end() 时,我只是让最后一个节点的下一个指针是nullptr。它独立工作,但与 stl 不同。

关于如何以与标准库相同的方式实现 begin()end() 的任何建议?

【问题讨论】:

标签: c++ list linked-list iterator stdlist


【解决方案1】:

你可以引入一个哨兵节点并有一个循环链表。

草图:

class List
{
    private:
    struct Node {
        Node* previous;
        Node* next;

        Node() : previous(this), next(this) {}
    };

    struct DataNode : Node {
        int data;
    };

    public:
    class iterator
    {
        friend class List;

        private:
        iterator(Node* node) : m_node(node) {}

        public:
        iterator() : m_node(0) {}

        iterator& operator ++() {
            m_node = m_node->next;
            return *this;
        }

        int& operator * () {
            // Note: Dereferncing the end (sentinal node) is undefined behavior.
            return reinterpret_cast<DataNode*>(m_node)->data;
        }

        // More iterator functions.

        private:
        Node* m_node;
    };

    public:
    List() : m_sentinal(new Node) {}

    iterator begin() { return iterator(m_sentinal->next); }
    iterator end() { return iterator(m_sentinal); }

    iterator insert(iterator position, int data) {
        DataNode* data_node = new DataNode; // pass data
        Node* current = position.m_node;
        data_node->next = current;
        data_node->previous = current->previous;
        current->previous->next = data_node;
        current->previous = data_node;
        return iterator(current);
    }

    void append(int data) {
        insert(end(), data);
    }

    private:
    Node* m_sentinal;
};

【讨论】:

  • 谢谢,哨兵的想法是我认为我需要的。谢谢!
【解决方案2】:

你的结束节点不能为空,因为如果你只有空,你就不能实现--(向后退)。您需要为至少知道如何返回到列表中的最后一个节点的结束节点创建一个哨兵。

【讨论】:

    【解决方案3】:

    您的容器应该创建一个始终可用的端节点。这是容器为空时从 begin() 返回的内容。您的最后一个真实节点应始终将其下一个节点设置为该端节点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-18
      • 2011-06-03
      • 2020-10-13
      • 1970-01-01
      • 2018-03-14
      • 1970-01-01
      • 2012-05-10
      相关资源
      最近更新 更多