簡體   English   中英

Linked List合並兩個列表,調試斷言錯誤

[英]Linked List merging two lists, debug assertion error

我有一個鏈接列表的合並實現。 它接受List類型的兩個參數,它是一個包含Node* head指針的類,以及一個由typename T dataNode* next組成的struct Node 我遇到的問題是我的實現不是應該連接節點,或者我可能只是錯了。 它需要做的是,如果你做list1.merge(list2, list3); 然后list1將成為list2和list3的節點的組合。 我需要通過指針操作來執行此操作並且不需要新的內存分配,因此將修改list2和list3。 這就是我現在所擁有的:

template <typename T>
void List<T>::merge(List& list1, List& list2) {

typename List<T>::Node* list1Ptr = list1.head;
typename List<T>::Node* list2Ptr = list2.head;

for(;;) {
    if (list1Ptr == NULL && list2Ptr != NULL) {
        list1Ptr = list2Ptr->next;
        head = list1.head;
        break;
    }
    else if (list2Ptr == NULL && list1Ptr != NULL) {
        list2Ptr = list1Ptr->next;
        head = list1.head;
        break;
    }
    else if (list1Ptr == NULL && list2Ptr == NULL) {
        head = list1.head;
        break;
    }
    else if (list1Ptr != NULL && list2Ptr != NULL) {

        if (list1Ptr->data > list2Ptr->data){
            typename List<T>::Node* temp;
            temp = list2Ptr->next;
            list1Ptr->next = list1Ptr;
            list2Ptr = temp;
        }
        else if (list1Ptr->data < list2Ptr->data) {
            typename List<T>::Node* temp;
            temp = list1Ptr->next;
            list1Ptr->next = list2Ptr;
            list1Ptr = temp;
        }
        else if (list1Ptr->data == list2Ptr->data) {
            list1Ptr = list1Ptr->next;
        }
    }
}
}

節點中包含的數據是為我們提供的類類型,它包含我們需要的所有正確的重載操作符。 整個代碼運行得很好,直到main超出范圍,析構函數被調用剩下的東西,之后我得到一個Debug Assertion Failed Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

我真的不知道該如何解決這個問題,我已多次抽出它,這對我來說似乎都有意義。 如果有人有任何提示讓我朝着正確的方向前進,我將非常感激。 謝謝大家的期待!

這不能按預期工作:

list1Ptr->data > list2Ptr->data && list1Ptr != NULL 
             && list2Ptr != NULL

在解除引用之前,您需要檢查指針是否為NULL,否則您將獲得未定義的行為。 (這意味着任何事情都可能發生,非常糟糕。)此外,您應該使用nullptr而不是NULL。

但是,這不是錯誤消息的原因,因為您已檢查其他條件中的所有NULL情況。

您的問題可能是建議的斜體。 如果您想要評論,請告訴我們其余的代碼。

對於初學者來說,這里有一些不妥之處:

    if (list1Ptr == NULL && list2Ptr != NULL) {
        list1Ptr = list2Ptr;
        head = list1.head;
        break;
    }

如果你完成了遍歷list1,那么你想要的是將list1的最后一個節點指向list2。 list1Ptr = list2Ptr;
什么都不做。 它只是改變局部變量的值。
這部分相同:

    else if (list2Ptr == NULL && list1Ptr != NULL) {
        list2Ptr = list1Ptr;
        head = list1.head;
        break;
    }

這是做事的壞事:
list1Ptr->data > list2Ptr->data && list1Ptr != NULL && list2Ptr != NULL
如果list1Ptr變為NULL,那么如果你試圖訪問NULL-> data肯定會有麻煩(因為通常表達式將從左到右執行)。
也:

        else if (list1Ptr->data > list2Ptr->data && list1Ptr != NULL 
             && list2Ptr != NULL) {
        typename List<T>::Node* temp = list2Ptr;
        list2Ptr = list2Ptr->next;
        temp->next = list1Ptr;
        }

這里也有一些問題。 您首先將list2ptr存儲在temp中。 然后將list2ptr移動到list2中的下一個節點。 但為什么要使temp->next = list1ptr
你應該重新思考這一部分。 對於下一個其他塊也一樣。
最好。
編輯:
好吧,讓我們看看還能做些什么:
這是我建議您使用的偽代碼:

func(list1,list2):
ptr1 = list1.head
ptr2 = list2.head
declare pointer curr
if(ptr1!= NULL and ptr2!=NULL){
    if(ptr1->data < prt2->data)
    {curr = ptr1
    ptr1 = ptr1->next
    head = curr
    }
    else{
    curr = ptr2
    ptr1 = ptr2->next
    head = curr}}
else{
    head = whichever one is not NULL, or NULL if both of them are and return
    }
while(ptr1 != NULL and ptr2!=NULL){
    if(ptr1->data < ptr2->data){
    curr->next = ptr1
    curr = ptr1
    ptr1 = ptr1->next
    continue}
    else{
    curr->next = ptr2
    curr = ptr2
    ptr2 = ptr2->next
    continue}
}
if(ptr1 == NULL)
    curr->next = ptr2
else
    curr->next = ptr1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM