双链表插入函数C ++

时间:2017-04-28 20:06:05

标签: c++ doubly-linked-list

基本上,我正在尝试创建一个函数,将值按顺序插入到双向链表中。

这个函数一直工作到第3个值,它似乎卡在while循环中:

template <class T>
void List<T>::insert_end(T item) {
    node<T> *newNode = new node<T>;
    newNode -> data = item;

    if (head == NULL && tail == NULL){
        head = newNode;
        tail = newNode;
        newNode -> next = NULL;
        newNode -> previous = NULL;
        ++len;
    }

    else {
        node<T> *cursor = head;
        while(cursor->next != NULL){
            cursor = cursor -> next;
        }
        cursor -> next = newNode;
        newNode -> previous = cursor;
        ++len;
    }
}

1 个答案:

答案 0 :(得分:1)

你的功能比它需要的更复杂。

对于初学者来说,拥有tail指针的重点是在列表末尾提供简单的插入和遍历,但是你完全忽略了tail。当列表不为空时,您的while循环将从前到后遍历列表,尝试查找列表中的最后一个节点 - tail已指向的节点。然后,当您将新节点添加到列表中时,您不会将tail更新为指向新节点。

您尝试编辑该函数以删除while循环(好),但您引入了一些新错误。如果列表中已包含任何节点,则不再分配newNode->previous。更糟糕的是,您将tail->next设置为head,这是完全错误的,因为它会为尝试从前到后遍历列表的任何代码创建无限循环。

该功能可以大大简化为以下内容:

template <class T>
void List<T>::insert_end(T item)
{
    node<T> *newNode = new node<T>;
    newNode->data = item;
    newNode->next = NULL;
    newNode->previous = tail;

    if (!head)
        head = newNode;

    if (tail)
        tail->next = newNode;
    tail = newNode;

    ++len;
}

insert_front()实施同样简单:

template <class T>
void List<T>::insert_front(T item)
{
    node<T> *newNode = new node<T>;
    newNode->data = item;
    newNode->next = head;
    newNode->previous = NULL;

    if (head)
        head->previous = newNode;
    head = newNode;

    if (!tail)
        tail = newNode;

    ++len;
}

话虽如此,如果可以的话,你真的应该使用STL的std::list类而不是手动列表实现。如果您想继续使用自己的类,可以轻松封装std::list,例如:

#include <list>

template<typename T>
class List
{
private:
    std::list<T> m_list;
    ...

public:
    ...
    void insert_front(const T &item);
    void insert_end(const T &item);
    ...
};

template<typename T>
void List<T>::insert_front(const T &item)
{
    m_list.push_front(item);
}

template<typename T>
void List<T>::insert_end(const T &item)
{
    m_list.push_back(item);
}