[英]Merge Two Sorted Lists got RUNTIME ERROR
這是我針對Leetcode的“合並兩個排序列表”算法問題的代碼:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *dummy, *pre;
dummy->next = l1;
pre = dummy;
while(l1 != NULL & l2 != NULL) {
if(l1->val < l2->val) {
pre = l1;
l1 = l1->next;
} else {
pre->next = l2;
l2->next = l1;
pre = l2;
l2 = l2->next;
}
}
if(l2 != NULL) {
pre->next = l2;
}
return dummy->next;
}
};
而且我遇到了運行時錯誤 。 但是我的代碼有什么問題?
我相信正確的實現將需要比OP中更多的代碼。 這是一個可以嘗試的正確實現。 我假設輸入列表l1
和l2
按降序排序(即從頭到尾從大到最小)。
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *pnt1 = l1;
ListNode *pnt2 = l2;
ListNode *head;
// assign the head pointer to larger head of the two input lists
if (l1->val > l2->val) {
head = l1;
}
else {
head = l2;
}
// walk through both lists sequentially,
// and splice together the sorted list
while (pnt1->next != NULL & pnt2->next != NULL) {
if(pnt2->val > pnt1->next->val && pnt1->val > pnt2->val) {
ListNode* next = pnt1->next;
pnt1->next = pnt2;
pnt1 = next;
}
else if(pnt2->val > pnt1->next->val && pnt1->val <= pnt2->val) {
ListNode* next = pnt2->next;
pnt2->next = pnt1;
pnt2 = next;
}
else if(pnt2->val <= pnt1->next->val && pnt1->val > pnt2->val) {
pnt1 = pnt1->next;
}
}
// handle edge case where end of one or two list(s) has been reached
if (pnt1->next == NULL && pnt2->next == NULL) {
if (pnt1->val > pnt2->val) {
pnt1->next = pnt2;
}
else {
pnt2->next = pnt1;
}
}
else if (pnt1->next == NULL) {
while (pnt2->next != NULL) {
if (pnt1->val > pnt2->next->val) {
ListNode* next = pnt2->next;
pnt2->next = pnt1;
pnt1->next = next;
break;
}
pnt2 = pnt2->next;
}
if (pnt2->next == NULL) {
pnt2->next = pnt1;
}
}
else if (pnt2->next == NULL) {
while (pnt1->next != NULL) {
if (pnt2->val > pnt1->next->val) {
ListNode* next = pnt1->next;
pnt1->next = pnt2;
pnt2->next = next;
break;
}
pnt1 = pnt1->next;
}
if (pnt1->next == NULL) {
pnt1->next = pnt2;
}
}
return head;
}
};
我認為您遇到了Segmentation Fault(Core Dump)
因為您嘗試訪問無效的內存:
dummy->next = l1;
在訪問它們的成員之前,應該為*dummy
和*pre
分配內存。
還可以在循環中使用&&
(邏輯運算符)代替&
(按位運算符)。 更換:
while(l1 != NULL & l2 != NULL) {
同
while(l1 != NULL && l2 != NULL) {
使用
new
運算符分配內存,請使用delete
釋放內存並避免內存泄漏。還要注意,實現本身在邏輯上是錯誤的。 請參考此處以獲得更好的實現。
這是一個簡單的遞歸實現:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
{
ListNode* result = NULL;
/* Base cases */
if (l1 == NULL)
return (l2);
else if (l2 == NULL)
return (l1);
if (l1->data <= l2->data)
{
result = l1;
result->next = mergeTwoLists(l1->next, l2);
}
else
{
result = l2;
result->next = mergeTwoLists(l1, l2->next);
}
return(result);
}
您的代碼中的主要問題是您正在使用:
dummy->next = l1;
當dummy
尚未初始化為指向有效對象時。
您還使用按位&
,其中邏輯&&
適當。
while(l1 != NULL & l2 != NULL) {
這是建議的實現。
PS尚未經過測試,但對我來說似乎正確。
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* ret = NULL;
ListNode* pre = NULL;
// Make sure the start of the list to be returned points to the right
// ListNode.
if ( l1 != NULL && l2 != NULL )
{
if ( l1->val < l2->val )
{
ret = l1;
l1 = l1->next;
}
else
{
ret = l2;
l2 = l2->next;
}
}
else if ( l1 != NULL )
{
return l1;
}
else
{
return l2;
}
pre = ret;
while(l1 != NULL && l2 != NULL) {
// Figure out where pre->next must point to.
// Advance l1 and l2 appropriately.
if(l1->val < l2->val) {
pre->next = l1;
pre = l1;
l1 = l1->next;
} else {
pre->next = l2;
pre = l2;
l2 = l2->next;
}
}
// Make sure pre->next points to the remaining ListNodes.
// They could be in l1 or l2.
if ( l1 != NULL )
{
pre->next = l1;
}
if( l2 != NULL)
{
pre->next = l2;
}
return ret;
}
除了已經指出的問題外,原始代碼無法處理首先到達列表2末尾的情況,在這種情況下,列表1的其余部分應附加到合並列表中。 使用指向指針的指針(而不是先前的指針)可使代碼更簡單。 這是合並兩個列表的示例代碼,以及使用合並列表功能的自底向上合並排序。 排序使用一個指向列表的指針數組,其中array [i]為null或指向其中包含pow(2,i)元素的列表。
ListNode * MergeLists(ListNode *pl1, ListNode *pl2)
{
ListNode *plm = NULL; /* merged list head ptr */
ListNode **pplm = &plm; /* ptr to head or prev->next */
if(pl1 == NULL)
return pl2;
if(pl2 == NULL)
return pl1;
while(1){
if(pl2->val < pl1->val){ /* if src2 < src1 */
*pplm = pl2;
pl2 = *(pplm = &(pl2->next));
if(pl2 == NULL){
*pplm = pl1;
break;
}
} else { /* src1 <= src2 */
*pplm = pl1;
pl1 = *(pplm = &(pl1->next));
if(pl1 == NULL){
*pplm = pl2;
break;
}
}
}
return plm;
}
#define NUMLISTS 32 /* number of lists */
ListNode * SortList(ListNode *pList)
{
ListNode * aList[NUMLISTS]; /* array of lists */
ListNode * pNode;
ListNode * pNext;
int i;
if(pList == NULL) /* check for empty list */
return NULL;
for(i = 0; i < NUMLISTS; i++) /* zero array */
aList[i] = NULL;
pNode = pList; /* merge nodes into aList[] */
while(pNode != NULL){
pNext = pNode->next;
pNode->next = NULL;
for(i = 0; (i < NUMLISTS) && (aList[i] != NULL); i++){
pNode = MergeLists(aList[i], pNode);
aList[i] = NULL;
}
if(i == NUMLISTS)
i--;
aList[i] = pNode;
pNode = pNext;
}
pNode = NULL; /* merge array into one list */
for(i = 0; i < NUMLISTS; i++)
pNode = MergeLists(aList[i], pNode);
return pNode;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.