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

时间:2016-03-11 14:45:58

标签: c++ linked-list

我正在尝试合并两个已排序的链接列表。在这里,我只想尝试实现自己的算法。当然,互联网上有很多解决方案。代码是:

zip

这只是一个返回合并链表的头地址的函数。

考虑这个输入/输出示例:

Node* MergeLists(Node *headA, Node* headB)
{
    int countA = 0, countB = 0;
    while(headA){countA++; headA = headA->next;}
    while(headB){countB++; headB = headB->next;}
    Node *res, *tres;
    res = new Node();
    res->next = NULL;
    tres = res;
    for(int i = 0; i < countA+countB-1; i++)
    {
        Node* temp = new Node();
        temp->next = NULL;
        tres->next = temp;
        tres = tres->next;
    }
    while(headA != NULL && headB != NULL)
    {
        if(headA->data > headB->data)
        {
            res->data = headB->data;
            res = res->next;
            headB = headB->next;
        }
        else if(headA->data < headB->data)
        {
            res->data = headA->data;
            res = res->next;
            headA = headA->next;
        }
    }
    while(headA)
    {
        res = headA;
    }
    while(headB)
    {
        res = headB;
    }
    return res;
}

所以,我的输出打印全部为零。这是由于这段代码中的问题:

Input (stdin):

3
4
1 3 5 6
3
2 4 7
1
15
1
12
0
2
1 2

My Output (stdout)

0 0 0 0 0 0 0
0 0
0 0

Expected Output
1 2 3 4 5 6 7
12 15
1 2

我认为tres和res之间的联系并没有正常发生。你能告诉我如何解决这个问题。

更新:

Node *res, *tres;
    res = new Node();
    res->next = NULL;
    tres = res;
    for(int i = 0; i < countA+countB-1; i++)// this is creating a new linked list.
    {
        Node* temp = new Node();
        temp->next = NULL;
        tres->next = temp;
        tres = tres->next;
    }

这次Node* MergeLists(Node *headA, Node* headB) { int countA = 0, countB = 0; Node* tempA, *tempB; tempA = headA; tempB = headB; while(headA){countA++; tempA = tempA->next;} while(headB){countB++; tempB = tempB->next;} Node *res, *tres; res = new Node(); res->next = NULL; tres = res; for(int i = 0; i < countA+countB-1; i++) { Node* temp = new Node(); temp->next = NULL; tres->next = temp; tres = tres->next; } while(headA != NULL && headB != NULL) { if(headA->data > headB->data) { res->data = headB->data; res = res->next; headB = headB->next; } else if(headA->data < headB->data) { res->data = headA->data; res = res->next; headA = headA->next; } } if(headA) { res= headA; //res = res->next; //headA = headA->next; } if(headB) { res = headB; //res = res->next; //headB = headB->next; } return res; }

4 个答案:

答案 0 :(得分:2)

问题在于这部分代码。

while(headA){countA++; headA = headA->next;}
while(headB){countB++; headB = headB->next;}

执行此循环后,headA&amp; headB指向NULL; 所以当

while(headA != NULL && headB != NULL)

循环开始,它甚至不进入循环。由于此循环负责分配值,因此它不会进入此循环。因此,您的所有值都设置为默认值0。

正如@Slava所说,你甚至不需要这个循环。由于您直接在节点上进行迭代,并且可以在NULL发生时停止。

创建临时指针并使用该指针计算countA和countB。

这样的东西
Node* temp;
temp = headA;
while(temp){countA++; temp = temp->next;}
temp = headB;
while(temp){countB++; temp = temp->next;}

此外,这可能会导致无限循环。请在循环内增加节点。或者只是将条件更改为if而不是while。

    while(headA)
    {
        res = headA;
    }
    while(headB)
    {
        res = headB;
    }

更新 -

另一个问题: 这个计算后返回的res,指向最后一个元素。因此输出只是一位数。

你能做的是

tres = res;
for(int i = 0; i < countA+countB-1; i++)
{
    ...
}
tres = res; // Add this line, so your keeping track of the original head
while(headA != NULL && headB != NULL)

最后return tres;而不是返回res;有了这个,你就会回到原来的头上。

答案 1 :(得分:1)

您不需要计算元素,预先创建结果列表并使用这么多循环,在一个循环中执行所有操作:

==

注意:您不应该从函数返回原始指针 - 它很容易导致内存泄漏。你应该使用智能指针。

答案 2 :(得分:0)

节点应包含某些内容 - 您正在创建一个新节点并将其分配到链的末尾,但根本不保存其中的值,因此该值可能只是默认为零。

答案 3 :(得分:0)

        res = res->next; <---

while(headA)
{
    res = headA;
}
while(headB)
{
    res = headB;
}
return res;

你返回res指向结尾而不是头部的指针。 另外,(headB / headA)假设在列表末尾添加提醒但实际上会循环无限,因为没有指针的增量。