在c++中删除链表中值的节点

Deleting nodes of a value in a Linked List in C++

本文关键字:节点 删除 c++ 链表      更新时间:2023-10-16

我在一个网站上练习编码,我不知道我在这个实现中做错了什么。有人能让我知道我在哪里错在我的代码?

函数removeElements应该从列表中删除所有具有给定值的元素。我试图通过使用另一个名为removeElement(单数)的函数来获取,并运行该函数,直到它无法删除任何东西。

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
    bool removeElement(ListNode* head, int val) {
        if (!head)
            return false;
        ListNode* iterator = head;
        //deal with case where head is value to be deleted
        if (head->val == val) {
            head = head->next;
            delete iterator;
            if (head == NULL)
                delete head;
            return true;
        }
        //head didn't match so iterate through list
        while (iterator->next) {
            if (iterator->val == val) {
                ListNode* temp = iterator->next;
                delete iterator;
                iterator = temp;
                return true;
            }
            iterator = iterator->next;
        }//end while loop
        //case where tail is value
        if (iterator->val == val) {
            delete iterator;
            return true;
        }
        //otherwise return false
        return false;
    }//end function removeElement
    ListNode* removeElements(ListNode* head, int val) {
        //Keep calling removeElement until it returns false.
        while (removeElement(head, val)) {
        }
        return head;
    }
};

从链接列表中删除内容的方法如下:

iter->prev->next = iter->next;
iter->next->prev = iter->prev;
delete iter;

这需要一个双重链表,这意味着每个元素都指向前一个元素。如果你不想(或不被允许)添加这个,你可以这样做:

if(iter->next && iter->next->val == val ){
   node* deleteMe = iter->next;
   iter->next = iter->next->next;
   delete deleteMe;
}

您的removeElement方法有许多问题。首先,如果它删除了头,调用者无法知道它的列表指针现在已被删除。

像这样操作列表的函数应该接受像这样的指针引用…bool removeElement(ListNode*& head, int val)。这样,如果函数改变了head的值,调用者就会得到新的值。

接下来,当像这样遍历单链表时,应该始终维护一个指向前一个元素的指针…

ListNode* current{head}, prev{nullptr};
while (current) {
    // do something interesting
    prev = current;
    current = current->next;
}

在您的情况下,您想要删除与给定条件匹配的节点…

size_t removeElements(ListNode*& head, int val) {
    size_t removed{0};
    ListNode* current{ head }, prev{ nullptr };
    while (current) {
        // Use a nested while loop to check for the condition.  
        // This simplifies the conditions for the outer loop.
        while (current->val == val) {
            ++removed;
            ListNode* oldCurrent = current;
            current = current->next;
            // If this is the head element, update the head value for the caller
            if (oldCurrent == head) {
                head = current;
            }
            // Update the previous element in the list, if any
            if (prev) {
                prev->next = current;
            }
            // delete the removed element
            delete oldCurrent;
        }
        prev = current;
        current = current->next;
    }
    // return the number of element removed.
    return removed;
}