簡體   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