删除单个链表中的元素

时间:2011-05-02 10:52:55

标签: c linked-list

在此代码中我将删除链表中的元素

11-> 12-> 13-> 14-> 15-> 12-> 16

如果我想删除12,它只删除第一次出现元素,即o / p将是

11-> 13-> 14-> 15-> 12-> 16

但我想删除所有12的发生,该怎么办?

任何人都可以给我一些意见吗?

    #include<stdio.h>
    #include<stdlib.h>
    void insertbeg();
    void delpos();
    void display();
    struct node
    {
            int info;
            struct node *link;
    }*first=NULL;

    struct node *create();
    int item,key;
    main()
    {
            int choice;
            while(1)
            {
                            printf("\nchoices are:\n");
                            printf("\n1.Insertbeg\n 2.delpos\n 3.display\n 4.exit\n");
                            printf("Enter U'r choice: ");
                            scanf("%d",&choice);
                            switch(choice)

                            {
                                            case 1: insertbeg(); break;
                                            case 2: delpos(); break;
                                            case 3: display(); break;
                                            case 4: exit(1);
                          default: printf("INVALID CHOICE TRY AGAIN\n");
                           }
            }
    }
    struct node *create()
    {
            struct node *new;
            new=(struct node*)malloc(sizeof(struct node));
            return(new);
    }
    void insertbeg()
    {
            struct node *new;
            new=create();
            printf("Enter element to be inserted: ");
            scanf("%d",&item);
            if(first==NULL)
            {
                            new->info=item;
                            new->link=NULL;
                            first=new;
            }
            else
            {
                            new->info=item;
                            new->link=first;
                            first=new;
            }
    }


    void delpos()
    {
            int key;
            struct node *temp,*prev;
            if(first==NULL)
            {
            printf("LIST IS EMPTY\n");
                            return;
            }
            else
            {
                            temp=first;
                            printf("Enter the KEY element which is to be deleted: ");
                            scanf("%d",&key);
                       /*     while(temp->info!=key&&temp->link!=NULL)
                    {
                                            prev=temp;
                                            temp=temp->link;
                            }
                            if(temp->info==key)
                     {
                                            prev->link=temp->link;
                                            free(temp);
                            }
                            else
                                          printf("key element not found in the list\n");
            */

                while(temp->link != NULL)
                    {
                        if(temp->info == key)
                        {
                        prev->link = temp->link;
                        free(temp);
                        temp = prev->link;
                        temp = temp->link; 
                        }
                        else
                            temp = temp->link;
                    }
            }
    }

    void display()
    {
            struct node *temp;
            temp=first;
            if(temp==NULL)
            {
                            printf("LIST IS EMPTY\n");
                            return;
            }
            else
            {
                            printf("Elements in Linked Lists: ");       

            while(temp!=NULL)
                            {
                                           printf("%d->",temp->info);
                                            temp=temp->link;
                            }
            }
    }

7 个答案:

答案 0 :(得分:1)

我可以发现您的代码存在两个问题,但是没有一个问题会导致您的示例输入出现问题。

1-

while(temp->link != NULL)

应该是

while(temp!=NULL)

2- temp = temp->link;

中是多余的
if(temp->info == key)
{
   prev->link = temp->link;
   free(temp);
   temp = prev->link;
   temp = temp->link; 
}

并跳过一个元素。

答案 1 :(得分:1)

如果您删除了第一个元素,那么您永远不会在此处输入while(temp->info!=key&&temp->link!=NULL)并且prev未初始化,prev->link将导致段错(因为您取消引用未初始化的指针)。

所以你可能会在这里得到它:prev->link=temp->link;

答案 2 :(得分:1)

我认为这里prev->link=temp->link上一个悬空。 如果它是第一个节点,只需移动指针并释放

答案 3 :(得分:1)

问题在于delpos:

prev->link=temp->link;

当您处于列表的第一个元素(即11)时,prev尚未设置为任何内容。 while循环

while(temp->info!=key&&temp->link!=NULL)

在这种情况下永远不会被执行,因此上一部分仍未设置。

另一个问题是当你删除列表的第一个元素时,变量首先仍将指向列表的原始第一个元素,而不是第二个元素。

一种解决方案就像是

 ...

 temp=first;
 prev=NULL;                  /* Added */
 printf("Enter the KEY element which is to be deleted: ");
 scanf("%d",&key);
 while(temp->info!=key&&temp->link!=NULL)
 {
     prev=temp;
     temp=temp->link;
 }
 if(temp->info==key)
 {
     if (prev==NULL)         /* Added */      
         first=temp->link;   /* Added */
     else                    /* Added */
         prev->link=temp->link;
     free(temp);
 }

 ...

答案 4 :(得分:0)

从文件中删除支票temp->info!=key,并使用if内部的那个部分来启动。

答案 5 :(得分:0)

最后,

不需要分配?

我可以在注释掉的部分看到它,但没有其他地方。显然,如果第一个元素与键匹配,则需要对其进行空检查。

答案 6 :(得分:0)

删除代码的主要问题是需要将第一个元素视为特殊情况,因为第一个元素可能是要删除的节点,因此首先可能需要使用新节点进行更新。可以通过使用像struct node ** temp = &first;这样的双指针来解决 。但是我试图接近你原来的帖子。

    // special condition if first should be removed.
    temp = first;
    while ( temp != NULL && temp->info == key ){
        first = temp->link;
        free(temp);
        temp = first;
    }

    // Here temp->info should not be removed(or it is NULL)
    // lets look at temp->link->info and remove temp->link
    while (temp!=NULL && temp->link != NULL) {
        if (temp->link->info == key) {

            struct node *to_free = temp->link;
            // temp checks the next node.
            temp->link = temp->link->link;
            free(to_free);
        } else {
            // next link
            temp = temp->link;
        }
    }

请注意,prev是不必要的。