c++,如何在删除重复项的同时横向链表

c++, How to transverse a linked list while deleting duplicates

本文关键字:链表 横向 删除 c++      更新时间:2023-10-16

问题:我有一个包含多个数字的.txt文件,我需要将这些数字按顺序排列并删除任何重复项。我已经制作了将它们整理好的功能(它有效)。我目前正在进行删除过程。

我不确定如何使它贯穿整个列表。因为如果前两个数字为 0,它只会删除第一个,然后函数结束。

无论如何,这就是我到目前为止的删除功能:

void deleteDuplicate(Node*& head) // head is the list with the ordered numbers
{
Node* tmpPtr;
Node* delPtr;
if (head == nullptr){
return;
}else if (head->data == head->next->data){
delPtr = head;
head = head->next;
delete delPtr;
}else{
tmpPtr = head;
delPtr = head->next;
while (delPtr != nullptr && delPtr->data != delPtr->next->data){
delPtr = delPtr->next;
tmpPtr = tmpPtr->next;
}
if (delPtr != nullptr){
tmpPtr->next = delPtr->next;
head = head->next;
delete delPtr;
}
}
}

在提供的源代码中,函数deleteDuplicate()揭示了分析中缺少的两个细节。通过选择在重复的情况下删除第一个节点,有必要更新到第一个节点的链接。

与其删除链表中的第一个节点,不如更轻松地 通过将第一个节点路由到第三个节点来删除第二个节点。

缺少分析 1- 第二个 if 条件必须与一般条件合并。

可以通过删除节点head->next而不是节点head来合并案例if (head->data == head->next->data)

只需删除第二个 if 条件:

if (head == nullptr){
return;
}
// to be managed in the else condition
//else if (head->data == head->next->data){
//  delPtr = head;
//  head = head->next;
//  delete delPtr;
//}
else{

缺少分析 2- 在所有重复的情况下删除第二个节点。

要删除第二个节点,请比较tmpPtr->datadelPtr->data而不是delPtrdelPtr->next.

替换以下 while 循环:

while (delPtr != nullptr && delPtr->data != delPtr->next->data){
delPtr = delPtr->next;
tmpPtr = tmpPtr->next;
}

通过强大的解决方案,同时循环:

while ((tmpPtr != nullptr) && (delPtr != nullptr)
&& (tmpPtr->data != delPtr->data)){
delPtr = delPtr->next;
tmpPtr = tmpPtr->next;
}

然后在删除中,不要更改head节点:

if (delPtr != nullptr){
tmpPtr->next = delPtr->next;
// not needed when deleting the second node
//head = head->next;
delete delPtr;
}

奖励- 添加一个 do-while 来浏览所有链表,一次调用deleteDuplicate()允许删除所有重复项!!

以下是完整的deleteDuplicate()函数:

void deleteDuplicate(Node*& head)
{
Node* tmpPtr;
Node* delPtr;
if (head == nullptr){
return;
}
else{
do {
tmpPtr = head;
delPtr = head->next;
while ((tmpPtr != nullptr) && (delPtr != nullptr)
&& (tmpPtr->data != delPtr->data)){
delPtr = delPtr->next;
tmpPtr = tmpPtr->next;
}
if (delPtr != nullptr){
tmpPtr->next = delPtr->next;
delete delPtr;
}
// explore all the linked list
} while (delPtr!=nullptr);
}
}