Обычно я бы не стал публиковать полный код чего-то, что было бы домашней работой, но я не был уверен, как правильно сформулировать все пункты. Я также не скомпилировал и не запустил это, потому что я не хотел создавать свой собственный класс Node.
Сначала мы можем поговорить об алгоритме. Если ваш односвязный список уже отсортирован и NULL завершен, то, по сути, у нас есть текущий узел, указывающий на узел в списке, и путевой узел (nextNode), который идет по списку. Главное, что нам нужно сделать, это обновить указатели, чтобы они указывали на следующий узел, как только мы нашли не дубликат.
В приведенном ниже коде я также добавил проверки NULL, что невероятно важный. Привыкайте точно знать, в каком состоянии могут находиться ваши переменные, так как легко случайно вызвать метод с нулевым указателем, что приведет к тому, что программа обработает sh.
Node* removeDuplicates(Node* root)
{
// Check that root isn't null before checking that its next pointer is also not NULL
if (root == NULL || root->next == NULL)
return root;
// Set up our current node and the travel node
Node* currentNode = root;
Node* nextNode = root->next;
// Until we've reached the end of the singly linked list
while (nextNode != NULL)
{
// Find the next node that isn't a duplicate
// Also check that we don't reach the end of the list
while (nextNode->data == currentNode->data && nextNode != NULL)
nextNode = nextNode.next;
// Update the current node's next pointer to point to the travel node
currentNode->next = nextNode;
// Update the current node to its next for the next iteration
currentNode = nextNode;
// Update the next node being careful to check for NULL
nextNode = nextNode == NULL ? NULL : nextNode->next;
}
return root;
}
Это не единственный способ справиться с этой проблемой. Реорганизуя, когда вы делаете определенные проверки и ассоциации, вы можете отменить некоторые проверки NULL или сделать программу более понятной. Это только одно из возможных решений.