以下是删除链接列表中重复元素的功能
void deleteDup(Node *head)
{
Node *ptr1, *ptr2, *prev;
for (ptr1 = head; ptr1 != NULL; ptr1 = ptr1->next){
prev = ptr1;
for (ptr2 = ptr1->next; ptr2 != NULL; prev = ptr2, ptr2 = ptr2->next){
if (ptr1->value == ptr2->value){
prev->next = ptr2->next;
free(ptr2); // Question 1
}
}
}
}
问题1:以上代码适用于(1->1->2->3->1)
。但在完成之后,我自己也感到困惑。
困惑:当它释放ptr2时它是如何在循环中向前移动的?释放ptr2后,prev = ptr2, ptr2 = ptr2->next
不应该出现seg错误吗?
问题2:此代码可以优化吗? (即节省资源或提高绩效)
答案 0 :(得分:1)
问题1:
确实存在问题。一般来说,你必须期望未定义的行为
(可以,但不一定是段错误
也可以没有错误地运行,但只能“可以”,不会。
for (ptr2 = ptr1->next; ptr2 != NULL;){
if (ptr1->value == ptr2->value){
prev->next = ptr2->next;
free(ptr2); // Question 1
}
else prev = ptr2;
ptr2 = prev->next;
}
这样的事情应该做(也许。我累了。)
问题2:最佳内存优化:
用指针删除列表并使用数组:p
时间选择:太。其他数据结构更适合这样的东西。
如果您在此过程中愿意留下更多记忆,
迭代列表并将每个元素插入到不同的数据中,例如某种树
在那里你可以很容易地检查元素是否在之前发生过
(并且在此仅一次迭代期间将其从列表中删除)
答案 1 :(得分:0)
绘制一个(部分)结构图,就像它在开头看一样。也许需要几个覆盖案例,如有趣的节点是第一个/最后一个/唯一一个。现在仔细考虑图表代码中的每个操作,在每个步骤之后检查没有出错。
同样的策略在确定如何进行操作时有效:图表之前/之后,以及如何从开始到结束。