繁体   English   中英

合并c++中的两个排序链表

[英]Merging two sorted linked list in c++

我正在尝试编写一个算法来合并两个排序的链表。 我无法理解为什么这不能给我正确的答案。 为什么答案没有早期作业的 memory ,它只返回最近完成的作业。 (即长度为1的链表)。 我正在创建一个名为cur的初始节点,然后根据l1l2的值向其添加next s,并每次都执行cur.next 谢谢

struct ListNode {
  int val;
  ListNode* next;
  ListNode() : val(0), next(nullptr){};
  ListNode(int x) : val(x), next(nullptr){};
  ListNode(int x, ListNode* next) : val(x), next(next){};
};

ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
  ListNode cur;
  ListNode* ans = new ListNode;
  ans = &cur;

  while (l1 && l2) {
    if (l1->val < l2->val) {
      ListNode temp(l1->val);
      cur.next = &temp;
      l1 = l1->next;
      cur = *(cur.next);
    } else {
      ListNode temp(l2->val);
      cur.next = &temp;
      l2 = l2->next;
      cur = *(cur.next);
    }
  }
  if (l1) {
    cur.next = (l1);
  }
  if (l2) {
    cur.next = (l2);
  }
  return ans->next;
};

主要问题是您没有向前移动cur以便可以将新节点附加到列表中。 正如你现在所拥有的, cur.next = &temp只是每次都重置next指针。 此外,由于temp变量是if分支的 scope 的本地变量,因此当您执行cur.next = &temp时,您将next指针设置为 object,每次if语句结束时该指针都会消失,从而导致悬空指针。 最好动态分配:

ListNode ans;
ListNode* cur = &ans;
while (l1 && l2) {
  if (l1->val < l2->val) {
    cur->next = new ListNode(l1->val);
    l1 = l1->next;
  } else {
    cur->next = new ListNode(l2->val);
    l2 = l2->next;
  }
  cur = cur->next;
}
if (l1)
  cur->next = l1;
else
  cur->next = l2;
return ans.next;

让我们浏览一下if块中的代码,以尝试了解发生了什么。

ListNode temp(l1->val);
cur.next = &temp;
l1 = l1->next;
cur = *(cur.next);

第 1 行在新分配的 memory 位置创建了一个名为 temp 的新 ListNode 变量。 假设这个 memory 位置的地址是 X123。 在这个 memory 位置,temp.val 存储 l1->val 并且 temp.next 为 nullptr。

第 2 行要求将临时变量的地址存储在 cur.next 中,因此 cur.next 将在第 2 行执行后存储 X123。

第 3 行要求使 l1 指向 l1->next。 这是在做你所期望的。

现在密切关注第 4 行。 它没有做你认为它正在做的事情。 在上面的评论中,您说:

我正在做 cur=*(cur.next),它应该向前移动 cur。

但这并不完全正确。 “向前移动 cur”没有意义,因为 cur 不是指向 ListNode 的指针,它只是一个 ListNode object。 So Line #4 is asking to copy the object stored at the memory location cur.next (ie memory location X123), and paste it into the memory location occupied by cur. 换句话说,它要求将临时 object 复制到当前 object 占用的 memory 位置。 所以在第 4 行执行后,cur.val 将存储 temp.val 中的任何内容(即最近的 l1->val),而 cur.next 将存储 temp.next 中的任何内容(即 nullptr)。

这样做会丢失指向 temp 的 memory 位置 X123 的指针,因为 cur.next 正在存储它,现在您已经用 nullptr 覆盖了它。 这就是为什么最后你对最后一个(最近的)作业有一个 cur 的原因。 由于您在每次迭代中都用新内容覆盖了 cur 的内容,因此所有早期的分配都将丢失。 你永远不会“向前移动”。

解决方案是使用指针。 让 cur 成为 ListNode* 指针而不是 ListNode object,并尝试解决问题。

希望这会有所帮助,欢迎来到 SO。 干杯!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM