在此代码中我将删除链表中的元素
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;
}
}
}
答案 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是不必要的。