void delete_double (LN*& l) {
if (l == nullptr)
return;
LN *p = l;
while ( p -> next != nullptr && p -> next -&g
Before or after you delete p, the item before p should point to the item after the two deleted items. Otherwise, the link list will broken.
Furthermore, for the while-loop, you may only stop when you arrive the last item. Otherwise, if the last two items are the same, you cannot correctly delete it.
Here is my version. I used a dummy item to point to the item before the current compared item. Notice this cannot deal with 3 items in a row.
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;
}
I have simplified the code above, the logic you have above also wont help you remove multiple duplicates. So lets look at the code below and dissect it:
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;
}
There seems to be a need for a dummy node at the start because if we have 1 -> 1 - > 2 we need to delete the first two and point to the correct head which is a 2. In order to avoid this confusion is better to keep a dummy node at the start and at the end just set the output of your list to be p = dummy.next, which is the actual start of your list.
I have defined some temporaries, temp
and duplicate
, temp to help me navigate further in the list and duplicate to hold the duplicate value, move the pointer to next and delete the node. prev
is the previous pointer to the node just before the duplicates.
Each node in the list, temp = p
I move forward until looking for the adjacent match p->value == temp->next->value
if there is a match I delete the current node and the one I found ahead of it. I use the prev
tracker to restore the order of the list by correctly setting its next
, else I break from my inner loop and move on to the next value, the outer loop p = p->next
.
I am not sure about your LN<T>
struct so I have gone ahead with what I think it is.
Demo Link