You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用链表实现归并排序时为何出现栈溢出错误?

排查链表归并排序的栈溢出问题

我帮你找到了栈溢出的核心原因——你的mid_element函数在拆分链表时,会导致无限递归,哪怕是只有5-6个元素的短链表也会触发这个问题。

问题分析

我们拿最简单的2节点链表(比如1->2)来举例:

  1. 调用MergeSort时,因为head->next != NULL,会进入拆分逻辑。
  2. 你的mid_element函数会返回第二个节点(2)。
  3. 拆分后,第一部分是原链表(head到mid,也就是1->2),第二部分是mid->next也就是NULL。
  4. 递归调用MergeSort(head)时,又会重复上述步骤:链表长度仍然大于1,再次找mid、拆分,永远无法触发递归终止条件(head->next == NULL)。

这种无限递归会不断消耗栈空间,最终导致栈溢出崩溃。

解决方案:修正mid_element函数

我们需要调整中间节点的查找逻辑,让它返回左半部分链表的最后一个节点,这样拆分后的左半部分不会包含整个链表,递归才能正常终止。

修正后的mid_element代码:

Node *mid_element(Node *head) {
    if(head == NULL || head->next == NULL)
        return head;
    Node *slow = head, *fast = head;
    // 循环条件改为检查fast的下一个和下下个节点,确保slow停在中间节点的前一个
    while(fast->next != NULL && fast->next->next != NULL) {
        fast = fast->next->next;
        slow = slow->next;
    }
    return slow;
}

额外优化:让Merge函数更健壮

虽然你提到Merge函数能正常工作,但当前实现没有处理其中一个链表为空的情况(虽然你的归并排序逻辑暂时不会传入空链表,但还是建议修正,避免潜在问题):

Node *Merge(Node *h1, Node *h2) {
    // 先处理空链表的边界情况
    if(h1 == NULL) return h2;
    if(h2 == NULL) return h1;
    
    Node *h, *t;
    // 确定头节点
    if(h1->data < h2->data) {
        h = h1;
        h1 = h1->next;
    } else {
        h = h2;
        h2 = h2->next;
    }
    t = h;
    
    // 合并剩余节点
    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;
}

验证修正效果

现在重新运行你的归并排序逻辑,不管是短链表还是长链表,都能正常拆分、递归排序并合并,不会再出现栈溢出问题。

内容的提问来源于stack exchange,提问作者Arman Atibudhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 07:22:32