链表删除节点,简单链表

问题描述 投票:1回答:2

我正在尝试实现从链接列表中删除节点的功能。到目前为止,我只可以删除list(3)的第一个节点。

我试图从delete转到for循环,我认为内存分配不正确,我已经苦苦挣扎了几天,我听不懂,请帮我一下,这是我收到的主题学院。

#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;
}
c struct linked-list singly-linked-list erase
2个回答
1
投票

对于初学者,您显示的代码不是C ++代码。这是C代码。

定义像firstlast这样的全局变量以及函数何时依赖于全局变量是一个坏主意。在这种情况下,您不能在一个程序中创建多个列表。

关于函数delete,则通常具有未定义的行为。可以将其称为空列表。

此外,在此循环中

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

条件表达式中有错字。您正在使用赋值运算符而不是比较运算符。

并且您的函数忽略列表仅包含一个节点的情况,因为在这种情况下,它不会更新最后一个节点。

尽管使用您的方法,函数删除可以按照以下方式进行。

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;
            }
        }
    }
}     

这里是演示程序。

#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;
    }

其输出为

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

-1
投票

我认为您的for循环条件在删除函数中不正确:

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

只要改变条件,它就应该起作用。

© www.soinside.com 2019 - 2024. All rights reserved.