为什么我使用此函数进行合并排序(使用链表)时会出现堆栈溢出错误?

Why do I get stack overflow error when I use this function for Merge Sort(using Linked Lists)?

我正在使用 mid_element() 函数来 return 中间节点的地址,并使用 Merge() 函数来合并两个已排序的链表。这两个功能都可以正常工作。但为了以防万一,我附上了代码。我经历了将链表分成两部分的合并排序算法,一个包含第一个节点到中间节点,另一个包含从 mid+1 到末尾的节点。当然,中间节点的下一个指针设置为空。然后我们在两半上递归调用合并排序,最后将两者合并。我做了同样的事情,但最终出现堆栈溢出错误。请帮忙。 中间元素函数:

Node *mid_element(Node *head)
{
    if(head==NULL || head->next==NULL)
        return head;
    Node *slow=head,*fast=head->next;
    while(fast!=NULL)
    {
        if(fast->next==NULL)
        {
            slow=slow->next;
            break;
        }
        else
        {
            fast=fast->next->next;
            slow=slow->next;
        }
    }
    return slow;
}

合并函数:

Node *Merge(Node *h1,Node *h2)
{
    Node *h=h1->data<h2->data?h1:h2,*t=h;
    h1=h1->next;
    while(h1!=NULL && h2!=NULL)
    {
        if(h1->data<h2->data)
        {
            t->next=h1;
            t=t->next;
            h1=h1->next;
        }
        else
        {
            t->next=h2;
            t=t->next;
            h2=h2->next;
        }
    }
    if(h1!=NULL)
        t->next=h1;
    if(h2!=NULL)
        t->next=h2;
    return h;
}

合并排序函数:

Node *MergeSort(Node *head)
{
    if(head==NULL || head->next==NULL)
        return head;
    else
    {
        Node *mid=mid_element(head);
        Node *temp=mid->next;
        mid->next=NULL;
        Node *res1=MergeSort(head);
        Node *res2=MergeSort(temp);
        Node *res=Merge(res1,res2);
        return res;
    }
}

节点定义:

class Node
{
public:
    int data;
    Node *next;

    Node(int data)
    {
        this->data=data;
        next=NULL;
    }

};

我正在使用一个函数来获取输入。用户输入 space 分隔的数字列表,-1 表示列表结束。输入函数:

Node *takeInput()
{
    int data;
    Node *head=NULL,*temp=NULL,*curr=NULL;
    do{
        cin >> data;
        if(data!=-1)
        {
            temp=new Node(data);
            if(head==NULL)
            {
                head=curr=temp;
            }
            else
            {
                curr->next=temp;
                curr=curr->next;
            }

        }
    }while (data!=-1);
    return head;
}

关于列表的大小,我只检查了只有 5-6 个元素长的列表,结果崩溃了。

Merge() 中的这一行取消引用了一个潜在的空指针。

Node *h=h1->data<h2->data?h1:h2,*t=h;

它可能为空,因为 mid_element() 包含此行

if(head==NULL || head->next==NULL)
    return head;

... 可以 return 一个指针,其 next 元素为空,并且 MergeSort() 取该 return 值,得到 next 元素可能为空,并将其传递给 Merge().

底线:在取消引用指针之前需要进行更多空值检查。