删除在链接列表中找到的所有特定密钥

deleting all specific keys found in linked list

本文关键字:密钥 链接 列表 删除      更新时间:2023-10-16

我正试图在一个函数中删除链接列表中的所有特定键元素。也就是说,如果链表有1 2 2 3 4 5 5 8 2 6 32 4 6 7,那么如果我通过该函数2,该函数将删除链表中的所有2

我的链接列表在这里

class float_list
{
     struct node
    {
        double data;
        struct node *next;
     };
        node *head;
public:
    float_list(void)
    {
        head = nullptr;
    };
    void appendNode(double);
    void print_list();
    void deleteNode(double);
};

现在是我的deleteNode(双人在这里)

void float_list::deleteNode(double num)
{
    node *nextptr, *previousptr = nullptr;
    nextptr=head;
    if(!head->data){return;}
    if(head->data==num)
    {
        nextptr= head->next;
        delete head; 
        head = nextptr;
    }
    else
        while(nextptr)
        {
            previousptr= nextptr;
            if(nextptr->data==num)
            {
                previousptr->next = nextptr->next;  
                delete nextptr;
                cout<<"I Found the  --> "<<num<<"  is going to be deleted"<<endl;
                nextptr = previousptr; 
                //nextptr = nextptr->next;
            }
            nextptr = nextptr->next;
        }
        delete nextptr;
        delete previousptr;
}

我尝试了各种不同的方式,但总是出现访问权限冲突错误。如果可能的话,请给我概念和代码提示。谢谢代码在win32 Vs2010应用程序中

while循环结束后会发生什么。好吧,nextptr==空。delete NULL==问题。

试试这个:

node *previous = nullptr, *current = head, *temp;
while(current){
    temp = current->next;
    if(abs(current->data - num) < MARGIN_OF_ERROR){
        if (previous){
            previous->next = current->next;
        } else {
            head = current->next;
        }
        delete current;
    } else{
        previous = current;
    }
    current = temp;
}

类似这样的东西(伪代码)

public void removeData( double data )
{
    if ( this.node == null ){ return; }
    if ( this.node->data == data ){
        this.node = this.node.node;
    }
    this.node.removeData( data );
}

我可以跟踪的两个问题:

  1. 永远不应该使用operator==来检查两个浮点值的相等性点数,浮点运算有问题-它们并不准确,结果可能并不像你所期望的那样[不是你的问题的解决方案,而是一个明确的问题]
  2. 你的previousptrnextptr是同一个东西[它们都指向同一个地址!]。您应该在当前迭代之前修改previousptr。[就在nextptr = nextptr->next;]之前]。因此,当您删除nextptr并稍后设置:时

            nextptr = previousptr; 
            nextptr = nextptr->next;
    

您实际上正在访问刚刚删除的元素,这会导致您的非法访问。

这可能可以通过递归完成,但这里有一个移动指针解决方案:

void removenumber(node **head, int value)
{
    node * current;
    node * prev;
    node * tmp;
    current = (*head);
    if ( current == NULL) return;
    prev = current;
    current = current->next;
    while( current!= NULL && current->next != NULL)
    {   
        if ( current->data == value)
        { //remove current
            tmp = current->next;
            prev->next = current->next;
            free(current);
            current = tmp;
            //previous is the same
            continue;
        }
        current = current->next;
        prev = prev->next;
    }
    // now current->next != NULL check it
    if(current!=NULL) //what is current was deleted?
    {
        if(current->data == value )
        {
            prev->next = NULL;
            free(current);
        }
    }
    if ( (*head)->data == value) //remove head
    {
        tmp = (*head)->next;
        free(*head);
        *head = tmp;
    }
}