簡體   English   中英

C ++中的合並排序單鏈接列表在大型輸入時失敗

[英]Merge Sort Singly Linked List in C++ failing for large input

更新。 其在FOR LOOP中的工作量為65,519。 如果我將其增加到65,520,它將失敗。 完全奇怪。

該程序不適用於大量輸入。 非常適合小投入。 我在Xcode上遇到異常。

Thread 1 : EXC_BAD_ACCESS (code=2, address = 0x7fff5f3fffb8).

請讓我知道如何繞過這個奇怪的錯誤。

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
typedef struct Node * nodePtr;

struct Node{

    int data;
    nodePtr next;

};

nodePtr globalHead;

void partition(nodePtr head, nodePtr *front, nodePtr *back){

    nodePtr fast;
    nodePtr slow;

    if (head == NULL || head->next == NULL){

        *front = head; // &a
        *back = NULL; // &b

    }else{

        slow = head;
        fast = head->next;

        while(fast != NULL){

            fast = fast->next;

            if(fast != NULL){

                slow = slow->next;
                fast = fast->next;

            }

        }

        *front = head; // a
        *back = slow->next; // b
        slow->next = NULL;
        //printList(*front);
        //printList(*back);

    }

}

nodePtr mergeLists(nodePtr a, nodePtr b){

    nodePtr mergedList = NULL;

    if (a == NULL){
        return b;
    }else if (b == NULL){
        return a;
    }

        try {



    if (a->data <= b->data){
        mergedList = a;
        mergedList->next = mergeLists(a->next, b);
    }else{
        mergedList = b;
        mergedList->next = mergeLists(a, b->next);
    }
    }
    catch (int e) {
        cout << "Error is . . " << e << endl;
    }

    return mergedList;

}

void mergeSort(nodePtr *source){

    nodePtr head = *source;
    nodePtr a = NULL;
    nodePtr b = NULL;

    if(head == NULL || head->next == NULL){

        return;

    }

    partition(head, &a, &b);

    mergeSort(&a);
    mergeSort(&b);

    *source = mergeLists(a, b);

}

void push(nodePtr *head, int data){

    nodePtr newNode = (nodePtr) malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = NULL;

    if ((*head) == NULL){
        *head = newNode;
        globalHead = *head;
    }else{
        (*head)->next = newNode;
        *head = newNode;
    }

}

void printList(nodePtr head){

    nodePtr current = head;
    while(current != NULL){
        printf("%d ",current->data);
        current = current->next;
    }
    printf("\n");

}

// *head = head in the main function,
// it is only there to connect the two and
// not let make the function return anything
// passed by reference
// globalHead points to the start of the linked list
// if you are passing the address over here you have to
// make a double pointer over there in the function

int main(void)
{
    nodePtr head = NULL;

    // linked list is formed from top to bottom fashion
    // push is done in constant time O(1)

    long long int i;


    //Pushing 200,000 Elements to the Linked List.
    for(i=1 ; i<=200000 ; i++) {
        push(&head, rand()%200000);
    }



    printList(globalHead);

    mergeSort(&globalHead);

    cout << "After Sorting . . \n";

    printList(globalHead);

    return 0;
}

使用遞歸mergeLists()是問題,它將為列表中的每個節點調用自身。 嘗試更改代碼,以使代碼循環並使用第二個指向節點的指針或可選的指向最初設置為&mergeList的節點的指針將節點附加到初始為空的mergeList上。 例如,使用名稱pMerge而不是mergeList:

Node * mergeLists(Node *a, Node *b)
{
Node *pMerge = NULL;                    // ptr to merged list
Node **ppMerge = &pMerge;               // ptr to pMerge or prev->next
    if(a == NULL)
        return b;
    if(b == NULL)
        return a;
    while(1){
        if(a->data <= b->data){         // if a <= b
            *ppMerge = a;
            a = *(ppMerge = &(a->next));
            if(a == NULL){
                *ppMerge = b;
                break;
            }
        } else {                        // b <= a
            *ppMerge = b;
            b = *(ppMerge = &(b->next));
            if(b == NULL){
                *ppMerge = a;
                break;
            }
        }
    }
    return pMerge;
}

這是使用指向列表aList []的指針數組對鏈表進行排序的快速方法的示例代碼,其中aList [i]指向大小為2的冪i列表,該列表利用了mergeLists()。

#define NUMLISTS 32                     // size of aList
Node * mergeSort(NODE *pList)
{
Node * aList[NUMLISTS];                 // array of pointers to lists
Node * pNode;
Node * 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 array
    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.

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