我正在尝试合并两个排序的链表。在这里,我只是尝试实现我自己的算法。当然,互联网上给出了许多解决方案。代码是:
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
因此,我的输出打印全部为零。这是由于这段代码中的问题:
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;
}
我认为 tres 和 res 之间的联系没有正确发生。你能告诉我如何纠正这个问题吗?
更新:
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;
}
这次~ no response on stdout ~
问题出在代码的这一部分。
while(headA){countA++; headA = headA->next;}
while(headB){countB++; headB = headB->next;}
执行此循环后,headA 和 headB 都指向 NULL;所以当
while(headA != NULL && headB != NULL)
循环开始,它甚至不进入循环。由于此循环负责分配值,并且不会进入此循环。因此,所有值都设置为默认值 0。
正如@Slava提到的,你甚至不需要这个循环。由于您直接迭代节点,并且可以在发生 NULL 时停止。
创建一个临时指针,并使用该指针计算计数 A 和计数 B。
类似的东西
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;有了这个,您将返回原始头部。
你不需要计算元素,预先创建结果列表并使用这么多循环,在一个循环中完成所有操作:
Node* MergeLists(Node *headA, Node* headB)
{
Node *res = nullptr;
Node **ptr = &res;
while( headA || headB ) {
Node *curr = new Node;
curr->next = nullptr;
*ptr = curr;
ptr = &curr->next;
if( headB == nullptr || ( headA && headA->data < headB->data ) ) {
curr->data = headA->data;
headA = headA->next;
} else {
curr->data = headB->data;
headB = headB->next;
}
}
return res;
}
注意:您不应该从函数返回原始指针 - 它很容易导致内存泄漏。您应该改用智能指针。
节点应该包含一些东西 - 您正在创建一个新节点并将其分配给链的末尾,但根本不在其中保存值,因此该值可能只是默认为零。
res = res->next; <---
while(headA)
{
res = headA;
}
while(headB)
{
res = headB;
}
return res;
您返回的 res 是指向末尾而不是头部的指针。加 while(headB/headA) 假设在列表末尾添加提醒,但实际上会无限循环,因为指针没有增量。