合并两个已排序的链接列表

时间:2017-05-23 15:28:23

标签: c++ c algorithm data-structures linked-list

我对这个问题有疑问:link我正在遵循这个解决方案:

if((headA==NULL)&&(headB==NULL)
    return NULL;
if((headA!=NULL)&&(headB==NULL))
    return headA;
if((headA == NULL)&&(headB!=NULL))
    return headB;
if(headA->data < headB->data)
    headA->next = MergeLists(headA->next, headB);
else if(headA->data > headB->data)
{
    Node* temp = headB;
    headB = headB->next;
    temp->next = headA;
    headA = temp;
    headA->next = MergeLists(headA->next, headB);
}
return headA;

我在headA->data < headB->data时得到它,然后我们只需将headA指针移动到下一个节点。但是当headA->data > headB->data时,我们创建一个临时指针,指向headA指向的位置并将headB移动到下一个节点。我不能得到的是:

  1. 以前排序的节点如何链接到我创建的这个新临时节点?你能否在我的代码上指出

  2. 此外,headA指针在第二个条件之后指向哪里?它是否指向新节点?

1 个答案:

答案 0 :(得分:1)

代码有效地将头元素从列表B移动到列表A。

Node* temp = headB;
headB = headB->next;

temp指向列表B头,headB指向列表B尾。实际上,列表B头已从列表中弹出。

temp->next = headA;

列表A现在附加到弹出的头部。

headA = temp;

列表A现在设置为列表,列表B中的原始头部后跟原始列表A.

然后合并就像列表A具有较小的头一样,它现在可以执行,因为列表B中的下一个元素不能小于它。

此代码无法处理两个列表具有相同头数据值的情况。在这种情况下,它只返回列表A而不合并尾部。

不确定为什么你不能在最后两种情况下这样做:

if(headA->data < headB->data) {
    headA->next = MergeLists(headA->next, headB);
    return headA;
}
else {
    headB->next = MergeLists(headA, headB->next);
    return headB;
}

保持简单和对称。

您还可以将前三种情况简化为以下两种情况:

if(headA == NULL)
    return headB;
if(headB == NULL)
    return headA;

这也可以在没有递归的情况下完成:

Node *merge_lists(Node *headA, Node *headB)
{
    Node *head;
    Node **nextPtr = &head;

    while (headA && headB) {
        Node **headMin = (headA->data < headB->data) ? &headA : &headB;
        *nextPtr = *headMin;
        nextPtr = &(*headMin)->next;
        *headMin = *nextPtr;
    }

    *nextPtr = headA ? headA : headB;
    return head;
}