首页 文章

C链表不会删除头节点

提问于
浏览
1

我有一个非常简单的节点类来实现链表(它只有数据和下一个指针) . 下面的函数应该删除其“data”= value的FIRST节点 . 功能正常 . 但是当我尝试删除第一个元素(列表的头部)时,却没有 . 那么,问题出在哪里?这是代码

class Node{
    public:
        int data;
        Node *next;
....some other functions...

};
void deleteNode(Node *n, int value){
    cout<<"after deleting node with data = "<<value<<" : ";
    if(n->data == value){
        n = n->next;        //I guess the problem is somewhere here!
        return;
    }
    while(n){
        if(n->next->data == value){
            n->next = n->next->next;
            return;
        }
        n = n->next;
    }
}

void printTheLinkedList(Node *n){
    while(n){
        cout<<n->data<<" --> ";
        n = n->next;
    }
    cout<<"NULL"<<endl;
}


int main(){
    Node N(0);
    for(int i = 1; i < 10; i++)
        N.appendNode(i);

    printTheLinkedList(&N);
    deleteNode(&N, 3);
    printTheLinkedList(&N);
    deleteNode(&N, 0);
    printTheLinkedList(&N);


    return 0;
}

这是代码的输出(注意:3被删除,但0不是)

0 --> 1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9 --> NULL
0 --> 1 --> 2 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9 --> NULL
0 --> 1 --> 2 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9 --> NULL

3 回答

  • 2

    您正在将局部变量 n 更改为 n->nextmain 中的头部值实际上并未更改 . 试试这个,返回新头 .

    Node* deleteNode(Node *n, int value){
        cout<<"after deleting node with data = "<<value<<" : ";
        if(n->data == value){
            n = n->next;        //I guess the problem is somewhere here!
            return n;
        }
        Node* root = n;
        while(n){
            if(n->next->data == value){
                n->next = n->next->next;
                return;
            }
            n = n->next;
        }
        return root;
    }
    

    然后打电话给:

    printTheLinkedList(&N);
    Node* head = deleteNode(&N, 3);
    printTheLinkedList(head);
    head = deleteNode(head, 0);
    printTheLinkedList(head);
    
  • 1

    首先,您对代码注释的猜测是正确的 . 这条线与这个问题有关 .

    有三个问题:

    • 无法删除根节点,因为它在堆栈上作为 main 函数的局部变量分配 .

    • 链接的节点需要封装在类似于 linked_list 容器数据结构的内容中 . 它将在内部(至少)存储指向链表的 head (例如,开头)的指针 . 如果删除了 head 节点,则可以将下一个指针设置为 head

    • 您的删除代码目前没有释放动态分配的节点,因此您的应用程序正在泄漏内存 .

    由于您使用C编码,因此您可以使用智能指针来处理自动释放 .

  • 0

    你把头定义为

    Node N(0);
    

    因此,您无法删除此节点(头部) . 您应该将head声明为Node的指针

    Node *N( nullptr );
    

    在这种情况下,该功能可以按以下方式查看

    void deleteNode( Node * &n, int value )
    {
        cout << "after deleting node with data = " << value << " : ";
    
        Node *current = n;
        Node *previous = nullptr;;
    
        while ( current && current->data != value )
        {
            previous = current;
            current = current->next;
        }
    
        if ( current )
        {
            if ( previous ) previous->next = current->next;
            else n = nullptr;
    
            delete current;
        }
    }
    

相关问题