Linked List Delete Node , Simple linked list

有些话、适合烂在心里 提交于 2021-02-17 02:08:34

问题


I'm trying to implement a function that deletes nodes from a linked list. So far, I can delete just the first node of the list(3).

I tried to go to the for loop from delete, I thought that the memory is not well allocated, I have been struggling for a few days and I don't understand, please help me a little, it's the topic I received from college.

#include <stdio.h>
#include <stdlib.h>

typedef struct nod
{
    int key;
    struct nod *urm;
} NOD;

NOD *first=0,*last=0;

void add(int x)
{
    NOD *p=(NOD*)malloc(sizeof(NOD));
    p->key=x;
    p->urm=0;
    if(0==first)
    {
        first=p;
        last=p;
    }
    else{
        last->urm=p;
        last=p;
    }
}

void delete(int x)
{
    NOD *q,*p;
    if(first->key==x)
    {
        p=first;
        first=first->urm;
        free(p);

    }
    else{
        for(p=q=first;p=0;q=p,p=p->urm)
        {
            if(p->key==x)
            {
            q->urm=p->urm;
            if(p==last)
            {
                last=q;
            }
            free(p);
            }
        }
    }
}

void show()
{
    for(NOD *p=first;p!=0;p=p->urm)
    {
        printf("%d ",p->key);
    }
    printf("\n");
}
int main()
{
    add(3);
    add(1);
    add(2);
    add(5);
    show();

    delete(2);
    show();

    return 0;
}

回答1:


For starters the code you showed is not a C++ code. It is a C code.

It is a bad idea to define global variables like first and last and when functions depend on global variables. In this case you can not create more than one list in a program.

As for the function delete then in general it has undefined behavior. It can be called for an empty list.

Moreover in this ;loop

for(p=q=first;p=0;q=p,p=p->urm)

there is a typo in the condition expression. You are using the assignment operator instead of the comparison operator.

And you function ignore the case when the list contains only one node because in this case it does not update the last node.

Nevertheless using your approach the function delete can look the following way.

void delete(int x)
{
    if ( first )
    {
        if ( first->key == x )
        {
            NOD *tmp = first;
            first = first->urm;

            free( tmp );

            if ( first == NULL ) last = NULL;
        }
        else
        {
            NOD *p = first;
            while ( p->urm != NULL && p->urm->key != x )
            {
                p = p->urm;
            }

            if ( p->urm != NULL )
            {
                NOD *tmp = p->urm;
                p->urm = p->urm->urm;

                free( tmp );

                if ( p->urm == NULL ) last = p;
            }
        }
    }
}     

Here is a demonstrative program.

#include <stdio.h>
#include <stdlib.h>

    typedef struct nod
    {

    int key;
    struct nod *urm;
    } NOD;

    NOD *first=0,*last=0;


    void add(int x)
    {

    NOD *p=(NOD*)malloc(sizeof(NOD));
    p->key=x;
    p->urm=0;
    if(0==first)
    {
        first=p;
        last=p;
    }
    else{
        last->urm=p;
        last=p;
    }

    }

void delete(int x)
{
    if ( first )
    {
        if ( first->key == x )
        {
            NOD *tmp = first;
            first = first->urm;

            free( tmp );

            if ( first == NULL ) last = NULL;
        }
        else
        {
            NOD *p = first;
            while ( p->urm != NULL && p->urm->key != x )
            {
                p = p->urm;
            }

            if ( p->urm != NULL )
            {
                NOD *tmp = p->urm;
                p->urm = p->urm->urm;

                free( tmp );

                if ( p->urm == NULL ) last = p;
            }
        }
    }
}  

    void show()
    {
        for(NOD *p=first;p!=0;p=p->urm)
        {
            printf("%d ",p->key);
        }
        printf("\n");
    }
    int main()
    {
        add(10);
        add(20);
        add(30);
        add(40);

        show();

        delete(30);
        show();

        add( 50 );
        add( 60 );
        add( 70 );
        add( 80 );
        show();

        delete(80);
        show();


    return 0;
    }

Its output is

10 20 30 40 
10 20 40 
10 20 40 50 60 70 80 
10 20 40 50 60 70 



回答2:


You can greatly simplify deleting a node from your list by using both a pointer-to-pointer to NOD and a pointer-to NOD to iterate over the list. This allows you to set the node at the current address to the node->urm eliminating the need to keep track of the previous node in the list, e.g.

/** delete node with key v from list (for loop) */
void delete (int v)
{
    NOD **ppn = &first;        /* pointer to pointer to first*/
    NOD *pn = first;            /* pointer to first */

    for (; pn; ppn = &pn->urm, pn = pn->urm) {
        if (pn->key == v) {
            *ppn = pn->urm;     /* set node at address to next node */
            free (pn);          /* free deleted node */
            break;
        }
    }
}

See Linus on Understanding Pointers for further discussion on the advantages of using the address of a node in addition to a pointer to node.




回答3:


I think your for loop condition is incorrect inside delete functions:

for(q=first, p=first->urm; p!=0; q=p, p=p->urm)

just change the condition, then it should work.



来源:https://stackoverflow.com/questions/61468120/linked-list-delete-node-simple-linked-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!