插入时链接列表错误

时间:2016-04-18 18:08:33

标签: c++ pointers linked-list

我试图用这样的C ++中的暴露节点实现一个简单的双向链表 (省略了一些方法,应该非常清楚它们的作用):

template<typename T>
class Node
{
public:
    Node(T _value)
    {
        m_Data = _value;
        m_HasParent = false;
        m_HasNext = false;
        m_Parent = NULL;
        m_Next = NULL;
    }
    void insertAfter(Node<T>* _item)
    {
        m_Next = _item;
        m_HasNext = true;
        _item->insertBefore(this);
    }
    void insertBefore(Node<T>* _item)
    {
        if(m_HasParent)
        {
            m_Parent->insertAfter(_item);
            _item->insertAfter(this);
        }
        else
        {
            m_Parent = _item;
            m_HasParent = true;
        }
    }
private:
    T m_Data;
    Node<T>* m_Parent;
    Node<T>* m_Next;
    bool m_HasParent;
    bool m_HasNext;
};

template<typename T>
class LinkedList
{
public:
    LinkedList()
    {
        m_Root = NULL;
        m_HasRoot = false;
    }
    ~LinkedList()
    {
        if(m_HasRoot)
        {
            delete m_Root;
        }
    }
    void pushFront(T _value)
    {
        if(m_HasRoot)
        {
            Node<T>* node = new Node<T>(_value);
            m_Root->insertBefore(node);
            node->insertAfter(m_Root);
            m_Root = node;
        }
        else
        {
            m_Root = new Node<T>(_value);
            m_HasRoot = true;
        }
    }
    void pushBack(T _value)
    {
        if(m_HasRoot)
        {
            Node<T>* last = m_Root;
            while(true)
            {
                if(last->getHasNext())
                {
                    last = last->getNext();
                }
                else
                {
                    break;
                }
            }
            Node<T>* node = new Node<T>(_value);
            last->insertAfter(node);
            return;
        }
        else
        {
            m_Root = new Node<T>(_value);
            m_HasRoot = true;
        }
    }

    T operator[](int _i)
    {
        Node<T>* last = m_Root;
        for(int i = 0; i <= _i; i++)
        {
            if(last->getHasNext())
            {
                last = last->getNext();
            }
            else
            {
                break;
            }
        }
        return last->getData();
    }
private:
    Node<T>* m_Root;
    bool m_HasRoot;
};

但是,在执行以下小测试时:

int main(int argc, char** argv)
{
    LinkedList<int> l;
    l.pushBack(0);
    l.pushBack(1);
    l.pushBack(2);
    l.pushBack(3);
    int count = l.getCount();
    std::cout << "count: " << count << std::endl;
    for(int i = 0; i < count; i++)
    {
        std::cout << "Value at [" << i << "]: " << l[i] << std::endl;
    }
    std::string s;
    std::cin >> s;
    return 0;
}

我希望看到按此顺序打印的数字0, 1, 2, 3,但这就是我得到的:

output

出于某种原因,插入背部并不是很有效。我发现我的代码没有任何根本错误,有人能发现问题吗?这是在MinGW 5.1,64bit,Windows 10 64bit上。但是,在runnable.com上执行此问题时,一切似乎都运行得很好?见this draft。这是MinGW中的错误还是我的一些错误?

编辑1

现在这很奇怪,有时似乎在runnable中运行,有时它会产生与我本地机器相同的结果......我完全糊涂了。

1 个答案:

答案 0 :(得分:3)

尝试将ListWidget::operator[]内的循环条件从i <= _i更改为i < _i_i等于0

应该没有迭代

标志是您从第二个元素开始打印,即1并打印最后一个元素两次。你忘记了根节点。

请注意,您正在检查某个节点是否有成功者,但您没有检查该列表是否为空(m_root != nullptr)。使其保持一致 - 要么删除UB的所有可能情况,要么不检查任何内容。