首先核心问题,为什么第一个元素无法被删除。查看您的删除逻辑,可以看到对于第一个节点就是要删除的节点的情况是特殊处理的,即和其他情况删除的方式不同。这里其实可以注意,当您确定问题“只在删除第一个节点时出现”,而您的实现中又“特殊处理了删除第一个节点的情况”,那就应该格外关注这一部分。在删除函数中,删除第一个节点的操作通过修改 head 指针的指向完成,然而应该注意,这一修改并未应用到后续被使用的 head 指针:指针是按值传递进入函数的,而函数返回的结果并未被使用。因此这一修改只在此函数中生效,当在此函数中完成删除之后从 head 开始遍历将得到正确的结果,但是返回主函数后并无效果。可以考虑的修改:使用返回值,如调用函数时使用或者改为按引用传递指针,即修改为// 声明
int delate(struct student **head);
// 主函数中
delate(&p);
// 重写此函数
int delate(struct student **head){ // 这里有改动
int i;
struct student *p1, *p2;
p1 = p2 = *head; // 这里有改动
printf("请输入删除学生的学号:");
scanf("%d", &i);
while (p2->next){
if (i == (*head)->num){ // 这里有改动
*head = p1->next; // 这里有改动
break;
}else if(i == p1->num){
p2->next = p1->next;
break;
}
p2 = p1;
p1 = p1->next;
}
return head;
}
另外,建议您注意错误的拼写(应为 delete 而不是 delate ),主函数必须返回 int ,删除函数的返回值类型错误,以及内存泄漏:您申请的空间完全没有释放,尽管在该程序中实际不会造成影响,但这是错误的、不应该的,等问题。链表建立的过程稍显繁琐而且会进行一次不必要的分配,这并不是错误(但是这次不必要的分配也没有释放,仍然是问题),也可能还有改进的空间。 |