我想编写一个代码来合并两个链接列表,使得结果列表具有无重复。这两个列表是有序的,但可能在它们中有重复。结果列表应存储在当前列表中。代码应该在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);
}
任何遗漏的信息?
答案 0 :(得分:3)
通过调用:
替换迭代器的每个增量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 :(得分:2)
以下方法有效,因为列表按降序排列,新列表也按降序构建。
在将下一个元素添加到新列表之前,只需添加一个支票:
if ( newNodeValue < lastAddedNodeValue )
//only then add to list.