删除单个链表中的元素

在这段代码中,我将删除链表中的元素

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

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

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

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

谁能给我一些投入?

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

我可以在您的代码中发现两个问题,但是没有一个问题会对您的示例输入产生问题。

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

并跳过一个元素。

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

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

我想这里的prev->link=temp->link prev是晃来晃去。 如果是第一个节点,只需移动指针即可

问题出在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); } ... 

从文件中删除check temp->info!=key ,并在while内部使用if来启动它。

最后,

不需要分配吗?

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

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

  // 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是不必要的。