>我使用 c 创建了一个简单的链表,我们可以在其中插入和删除列表中的任何位置的元素。代码工作正常,直到我尝试使用以下代码删除第一个节点。
typedef struct l_list
{
int data,index;
struct l_list *next_node;
}node;
static int total_node=0;
node *search(node *,int,node **);
int main()
{
int choice,key;
char ans;
node *new_node,*head, *p_node,*index_change,*cur;
node *get_node();
head=NULL;
printf("Program for Linked List.n");
do
{
printf("n1. Create Node");
printf("n2. Delete Node");
printf("n3. Traverse the List");
printf("n4. Exit");
printf("nEnter your choice: ");
scanf("%d",&choice);
switch(choice)
{
case 1:
do
{
total_node++;
new_node=get_node();
printf("nEnter the data you want to insert: ");
scanf("%d",&new_node->data);
if(head==NULL)
{
head=new_node;
head->index=1;
}
else
{
printf("nWhich node you want to insert it as:n");
for(int i=1;i<=total_node;i++)
{
printf("%d ",i);
}
printf("==) ");
scanf("%d",&key);
//printf("bb-|-");
if(key==1)
{
new_node->next_node=head;
head=new_node;
}
else
{
p_node=search(head,key,&cur);
new_node->next_node=p_node->next_node;
p_node->next_node=new_node;
//p_node=NULL;
}
new_node->index=key;
index_change=new_node->next_node;
while(index_change!=NULL)
{
index_change->index=++key;
index_change=index_change->next_node;
}
}
printf("nDo you want to insert more node in the linked list: [y/n]");
//ans=getch();
}while((ans=getch())=='y');
break;
//Deletion code.
case 2:
do
{
if(head==NULL)//head is first node of the list
{
printf("nUNDERFLOW!nThe linked list is already empty.n");
}
else
{
printf("Which node you want to delete:n");
for(inti=1;i<=total_node;i++)
printf("%d ",i); //total_node=variable taken
printf("==) "); //to track the total no of node
scanf("%d",&key); //key=node index to be deleted
//printf("bb-|-");
if(key==1)
{
//If we need to delete the first node when only one node is left
if(total_node==1)
{
//p_node=head;
head=NULL;
}
//If we need to delete the first node when more than one node are there
else
{
//p_node=head;
head=head->next_node;
}
total_node--;
}
else
{
p_node=search(head,key,&cur);//returns node just before the node to be deleted
p_node->next_node=cur->next_node;//cur gets the value of the node that is to be deleted.
total_node--;
}
index_change=p_node->next_node;
while(index_change!=NULL)//to change the index of following nodes.
{
index_change->index=key++;
index_change=index_change->next_node;
}
}
printf("nDo you want to delete more nodes: [y/n]n");
}while((ans=getch())=='y');
case 3:
if(head==NULL)
printf("nThe linked list is empty.n");
else
{
printf("nThe elements of linked lists are as follows:nn");
p_node=head;
while(p_node!=NULL)
{
printf("[%d]->%d ",p_node->index,p_node->data);
p_node=p_node->next_node;
}
}
break;
}
}while(choice!=4);
return 0;
}
node *get_node()
{
node *temp1;
temp1= new node;
temp1->next_node=NULL;
return temp1;
}
node *search(node *head,int key,node **cur)
{
node *current,*prev;
current=head;
while(current!=NULL)
{
if(current->index==key)
{
return prev;
}
prev=current;
current=current->next_node;
*cur=current;
}
return prev;
}
如果我尝试删除第一个节点,请使用此代码,程序会崩溃。当我使用临时变量时,例如
if(key==1)
{
if(total_node==1)
{
p_node=head;
head=NULL;
}
else
{
p_node=head;
head=p_node->next_node;
}
total_node--;
}
程序工作正常。所以我想问的是,我们可以直接删除头节点,还是总是需要另一个临时结构指针来删除头节点。
在这一行中:
index_change=p_node->next_node;
你取消引用p_node
.但是,在删除第一个节点的情况下,不会为 p_node
设置值。您观察到的崩溃可能是因为p_node
没有保存有效的内存地址。
如果没有您得到的确切错误和完整的程序,很难说发生了什么。
立即看起来错误的一件事是你分配节点(你的struct Linked_List
),其中包括数据。这不是您想要的链表。在链表中,您只想修改指针,并阻止复制数据。
另外,你的程序结构非常糟糕。请考虑将特定操作移动到单独的函数中,并为每个函数编写测试。这也将允许您发布简洁、完整的代码示例以及您的问题。
为了消除错误,您可以使用调试器,也可以向代码中添加 print 语句,告诉您发生了什么。
在这一行中:
p_node=search(head,key,&cur);//returns node just before the node to be deleted
如果您尝试删除第一个节点,则传递head
指针,该指针已设置为 NULL
。
因此,您不能取消引用代码必须执行的 search
函数中的head
指针(我相信),因为您没有任何其他方法可以到达链表的开头。