void delete_double (LN<T>*& l) {
if (l == nullptr)
return;
LN<T> *p = l;
while ( p -> next != nullptr && p -> next -> next != nullptr)
{
if (p -> value == p -> next -> value) // the current value is equal to the next value in the linked list
{
if (p == l) // when the first two values are the same // not sure if it is correct
{
l = l -> next -> next;
}
else // Problem should be here
{
LN<T> *to_delete = p; // Also tried this (doesn't work)
p = p->next;
delete to_delete; // LN<T>* to_delete = p;
// LN<T>* to_delete2 = p -> next;
LN<T> *to_delete1 = p; // l = to_delete2 -> next;
p = p->next; // delete to_delete;
delete to_delete1; // delete to_delete2;
}
}
else
{
p = p-> next;
}
}
}
// Image below is my output
嗨,我正在编写一个函数,如果两个值相同,将删除链表中一行中的两个值。当输入类似于&#34; 1 - &gt;时,我的代码似乎停止工作。 2 - &gt; 3 - &gt; 3 - &gt; 4 - &gt; nullptr&#34;。(输出应该是1 - > 2 - > 4 - > nullptr)。它退出时没有给我任何错误。我逐行完成了调试,只是突然退出并显示&#34;变量不可用&#34;。
我猜这是问题,当我删除p时,l指向垃圾,这会导致问题。所以我尝试了一种不同的方式让我指向to_delete - &gt;下一个。但它仍然无效。
我已经尝试了这么多时间来修复它,调试甚至没有帮助。有人可以帮忙吗?非常感谢!
答案 0 :(得分:0)
在删除p之前或之后,p之前的项目应指向两个已删除项目之后的项目。否则,链接列表将被破坏。
此外,对于while循环,您可能只在到达最后一个项目时停止。否则,如果最后两个项目相同,则无法正确删除它。
这是我的版本。我使用虚拟项目指向当前比较项目之前的项目。请注意,这不能连续处理3个项目。
void delete_double (LN<T>*& l) {
if (l == nullptr)
return;
LN<T> *dummy = new LN<T>;
dummy -> next = l;
while ( dummy -> next != nullptr && dummy -> next -> next != nullptr) // search until the last but two item
{
if (dummy -> next -> value == dummy -> next -> next -> value) // the current value is equal to the next value in the linked list
{
dummy -> next = dummy -> next -> next -> next; // link the item after dummy to the item after the deleted items
}
dummy = dummy -> next; // move dummy to the next, notice that this cannot deal with 3 items in a row
}
return;
}
答案 1 :(得分:0)
我已经简化了上面的代码,上面的逻辑也无法帮助您删除多个重复项。所以让我们看下面的代码并解析它:
void delete_double(LN<T>*& l) {
if (l == nullptr)
return;
LN<T> *p = l;
LN<T> dummy(0);
dummy.next = l;
p = &dummy;
LN<T> *temp;
LN<T> *duplicate;
LN<T> *prev;
while (p != nullptr && p->next != nullptr)
{
temp = p;
while (p != nullptr && temp->next != nullptr)
{
if (p->value == temp->next->value)
{
duplicate = temp->next;
temp->next = temp->next->next;
delete duplicate;
duplicate = p;
prev->next = p->next;
p = prev;
delete duplicate;
temp = p;
}
else
{
break;
}
}
prev = p;
p = p->next;
}
l = dummy.next;
}
一开始似乎需要一个虚拟节点,因为如果我们有1 - &gt; 1 - &gt; 2我们需要删除前两个并指向正确的头是2。为了避免这种混淆,最好在开始时保持一个虚拟节点,最后只需将列表的输出设置为p = dummy.next,这是列表的实际开始。
我已经定义了一些临时值temp
和duplicate
,temp可以帮助我在列表中进一步导航并复制以保存重复值,将指针移动到next并删除节点。 prev
是指向重复项之前的节点的前一个指针。
列表中的每个节点temp = p
我向前移动,直到找到相邻的匹配p->value == temp->next->value
如果匹配,我删除当前节点和我之前找到的节点。我使用prev
跟踪器通过正确设置其next
来恢复列表的顺序,否则我会从内部循环中断并继续前进到下一个值,即外部循环p = p->next
。
我不确定你的LN<T>
结构,所以我已经按照我的想法行事。