我使用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("\b\b-|-");
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("\b\b-|-");
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:\n\n");
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--;
}
程序正常运行。所以我想问的是我们可以直接删除头节点,或者我们总是需要另一个临时结构指针来删除头节点。
答案 0 :(得分:2)
在这一行:
index_change=p_node->next_node;
你取消引用p_node
。但是,如果删除第一个节点,则不会为p_node
设置值。您观察到的崩溃可能是因为p_node
没有有效的内存地址。
答案 1 :(得分:1)
如果没有你得到的确切错误以及完整的程序,很难说出现了什么。
立即出现错误的一件事是您分配节点(您的struct Linked_List
),其中包含数据。这不是你想要的链表。在链表中,您只想修改指针,阻止复制数据。
另外,你的程序结构非常糟糕。考虑将特定操作移动到单独的函数中,并为每个函数编写测试。这也允许您在问题中发布简洁,完整的代码示例。
为了关闭错误,您可以使用调试器,也可以在代码中添加打印语句,告诉您发生了什么。
答案 2 :(得分:0)
在这一行:
p_node=search(head,key,&cur);//returns node just before the node to be deleted
如果您尝试删除第一个节点,则传递已设置为head
的{{1}}指针。
所以你不能取消引用你的代码必须做的NULL
函数内的head
指针(我相信),因为你没有任何其他方法可以到达链表的开头