繁体   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