Я хочу написать код для слияния двух связанных списков, чтобы в результирующем списке не было дублирования. Эти два списка упорядочены, но могут иметь дублирование внутри них. Полученный список должен быть сохранен в текущем списке. Код должен работать в O(n1+n2)
где n1 - размер текущего списка, а n2 - размер другого списка.
Это код, который объединяет два списка, но с дублированием. Время работы этого кода - O(n1+n2)
и он сохраняет полученный список в текущий список:
template <class T>
void DLList<T>::MergeInOrder(DLList<T>& otherList)
{
if(otherList.IsEmpty() == true)
return;
if(IsEmpty() == true)
{
Append(otherList);
return;
}
DLList<T> newList;
DLLNode<T> *thisPtr, *otherPtr;
for(thisPtr = this->head, otherPtr = otherList.head;
thisPtr != NULL || otherPtr != NULL; )
{
if(otherPtr == NULL)
{
newList.AddToTail(thisPtr->val);
thisPtr = thisPtr->next;
}
else if(thisPtr == NULL)
{
newList.AddToTail(otherPtr->val);
otherPtr = otherPtr->next;
}
else if(thisPtr->val <= otherPtr->val)
{
newList.AddToTail(thisPtr->val);
thisPtr = thisPtr->next;
}
else
{
newList.AddToTail(otherPtr->val);
otherPtr = otherPtr->next;
}
}
Clear();
Append(newList);
}
Любая недостающая информация?
Следующее будет работать, так как списки находятся в порядке убывания, и новый список также создается в порядке убывания.
Перед добавлением следующего элемента в новый список просто добавьте проверку:
if ( newNodeValue < lastAddedNodeValue )
//only then add to list.
Замените каждое приращение итератора вызовом:
DLLNode<T>* nextDifferent(DLLNode<T> &node)
{
const T& val = node.val;
DLLNode<T> *res = node.next;
while (res != nullptr && res->val == val) {
res = res->next;
}
return res;
}
поэтому thisPtr = thisPtr->next;
стать thisPtr = nextDifferent(*thisPtr);
,
РЕДАКТИРОВАТЬ
Ваша петля должна выглядеть примерно так:
for (thisPtr = this->head, otherPtr = otherList.head;
thisPtr != NULL && otherPtr != NULL; )
{
if (thisPtr->val < otherPtr->val)
{
newList.AddToTail(thisPtr->val);
thisPtr = nextDifferent(*thisPtr);
}
else if (otherPtr->val < thisPtr->val)
{
newList.AddToTail(otherPtr->val);
otherPtr = nextDifferent(*otherPtr);
} else { // they are equal
newList.AddToTail(otherPtr->val);
otherPtr = nextDifferent(*otherPtr);
thisPtr = nextDifferent(*thisPtr);
}
}
while (otherPtr != NULL)
{
newList.AddToTail(otherPtr->val);
otherPtr = nextDifferent(*otherPtr);
}
while (thisPtr == NULL)
{
newList.AddToTail(thisPtr->val);
thisPtr = nextDifferent(*thisPtr);
}
1 1
и2 2
. Этот код добавит оба1
с подряд, потому что они оба меньше2
.