删除双向链表中的功能故障

时间:2016-08-04 23:29:04

标签: c++ linked-list doubly-linked-list

我从双向链表中删除节点的功能是向列表中添加(覆盖?)值,这些值在打印列表时出现。

主要,删除和打印功能的代码如下所示。当前代码与其输出之间的预期输出和相关性也如下所示。

主要代码

在main中,调用add函数,并将参数中的整数作为节点添加到链表中。添加功能和打印功能一样有效。

int main()
{
    LinkedList aList;

    aList.add(3);
    aList.add(10);
    aList.add(1);
    aList.add(7);
    aList.add(9);
    aList.add(12);
    aList.printAscending();
    aList.printDescending();
    aList.remove(3);
    aList.remove(1); //The integer to be removed with this line ends up in the output
    aList.remove(7);
    aList.remove(12);
    cout << "remove operations should be complete" <<endl;
    aList.printAscending();
    aList.printDescending();

    return 0;
}

删除功能代码

bool LinkedList::remove(int val) //parameter contains value to be removed
{
    bool removed = false;
    Node* newNode = new Node;
    newNode->data = val;
    newNode->next = NULL;
    newNode->prev = NULL;

    Node* curr = head;
    while(curr)
    {
        if(curr->data == val)
        {
            if(curr == head)
            {
                head = head->next;
                curr->next = NULL;
                delete curr;
            }

            else if(curr != head && curr != tail)
            {
                Node * previous = curr->prev;
                Node * following = curr->next;
                previous->next = following;
                following->prev = previous;
                curr->next = NULL;
                curr->prev = NULL;
                delete curr;
            }

            else if(curr == tail)
            {
                tail = tail->prev;
                curr->prev = NULL;
                delete curr;
            }
            removed = true;
        }
        curr = curr->next;
    }
    return removed;
}

打印功能代码

//Prints from head to tail of list
void LinkedList::printAscending() const
{
    Node* curr = head;
    cout<<"\nascending: ";
    while(curr)
    {
        cout << curr->data << " ";
        curr = curr->next;
    }
    cout <<'\n';
}

//Prints from tail to head of list
void LinkedList::printDescending() const
{
    Node* curr = tail;
    cout << "\ndescending: ";
    while(curr)
    {
        cout << curr->data << " ";
        curr = curr->prev;
    }

    cout << endl;
}

预期输出

ascending: 3 10 1 7 9 12
descending: 12 9 7 1 10 3
remove operations should be complete
ascending: 10 9
descending: 9 10

实际输出

ascending: 3 10 1 7 9 12                  //correct
descending: 12 9 7 1 10 3                 //correct
remove operations should be complete      //correct
ascending: 10 9 0                         //last number, 0, is incorrect
descending: 9 10 1                        //last number, 1, is incorrect

如果int main中用于删除整数1 aList.remove(1)的调用替换为aList.remove(999),则整数999将显示在降序打印的实际输出中,而不是1。但是,整数0随时附加到升序打印。

2 个答案:

答案 0 :(得分:1)

删除$resource('/api/path',{ queryParameter: (function process(queryParameter) { //process queryParameter return processed_query_parameter; })(queryParameter), }); 后,您将其取消引用:

curr

这是未定义的行为

答案 1 :(得分:1)

除了Beta指出的未定义行为,你的头部和尾部的特殊情况都有问题。通过调试器运行它并在每次删除后检查列表中的值会显示出现了什么问题。

此代码:

        else if(curr == tail)
        {
            tail = tail->prev;
            curr->prev = NULL;
            delete curr;
        }

对第二个最后一个元素的next指针没有任何作用。这意味着你的倒数第二个元素(然后成为最后一个元素)有一个指向释放内存的next指针。

要修复它,您需要将最后一个元素的next指针设置为null。像这样:

        else if(curr == tail)
        {
            tail = tail->prev;
            tail->next = NULL;
            curr->prev = NULL;
            delete curr;
        }

但是等等! (几乎*)无法保证前一个元素存在(即在1个元素列表中),因此您需要检查新尾部是否为NULL。

        else if(curr == tail)
        {
            tail = tail->prev;
            if (tail != NULL)
               tail->next = NULL;
            curr->prev = NULL;
            delete curr;
        }

*实际上,如果这是一个单一的元素列表,你就不会达到这个代码,你已经经历过&#34; head&#34;如果是测试代码,它有类似的问题,因为它不会改变第二个节点的prev指针。

所以你需要在&#34; head&#34;中进行相同类型的测试。如果测试代码。

完成后,您可能会发现可以重新排列测试以摆脱重复的代码。