Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 链表的合并排序_C_Algorithm_Data Structures_Linked List - Fatal编程技术网

C 链表的合并排序

C 链表的合并排序,c,algorithm,data-structures,linked-list,C,Algorithm,Data Structures,Linked List,我有一个用于无序链表的Mergesort源代码,如下所示。假设我已经完成了merge函数,z是sentinel键 node *mergesort(node *c) { node *a, *b; if (c->next != z) { a = c; b = c->next->next->next; while (b != z) { c = c->next;

我有一个用于无序链表的Mergesort源代码,如下所示。假设我已经完成了
merge
函数,
z
是sentinel键

node *mergesort(node *c)
{
    node *a, *b;
    if (c->next != z)
    {
        a = c;
        b = c->next->next->next;
        while (b != z)
        {
            c = c->next;
            b = b->next->next;
        }
        b = c->next;
        c->next = c;
        return merge(mergesort(a), mergesort(b));
    }
    return c;
}
我对此实施有3个怀疑:

  • 如您所见,
    b
    指向链接列表的第三个元素。我不知道为什么,因为我认为只要是
    b=c->next
    就足够了

  • 在循环
    中,
    还有
    b=b->next->next
    ,据我所知,它继续指向该数组中
    c
    之后的第四个元素。如果我写
    b=b->next
    ,可以吗

  • 根据我对
    mergesort
    算法的理解,它将数组分为两个子数组
    a
    b
    ,然后递归地对每个子数组进行合并排序,但我只看到它只对数组
    b
    起作用。这个实现有什么问题吗


  • 此代码中存在多个问题:

    • b=c->next->next->nextc->next->next
      为空,则code>具有未定义的行为
    • b=b->next->nextb->next
      为空,则code>具有未定义的行为
    • 列表在
      b
      之前没有正确分割,而且
      c->next=c创建一个循环,该循环将导致算法因无限循环而失败
    该功能需要进行重大更改以解决这些问题

    以下是修改后的版本:

    node*mergesort(node*c){
    节点*a,*b;
    /*测试列表是否至少有2个元素*/
    如果(c!=z&&c->next!=z){
    /*找到中间节点*/
    a=b=c;
    而(b->next!=z&&b->next->next!=z){
    c=c->next;
    b=b->next->next;
    }
    /*在c和c之间拆分列表->下一步*/
    b=c->next;
    c->next=z;
    /*对两个子列表进行排序并合并它们*/
    返回merge(mergesort(a),mergesort(b));
    }
    返回c;
    }
    
    它的意图似乎是通过将头部保持在
    a
    中,然后将
    c
    移动到中间点,让另一个指针
    b
    移动两倍,然后在
    b
    到达终点时停止
    c
    移动来分割列表。然而,关于如何标记端点,人们还存在一些困惑。一半的代码似乎认为它使用了一个特殊的
    z
    ,一半的代码似乎认为它使用了一个自链接(如
    c->next=c
    )来表示结束。@bg2b这是我真正感到困惑的地方。我认为这里可能有问题,但我不知道是什么。是的,我认为我的观点是正确的,但我不确定。最后一个问题呢?@chqrlie这不只是试图访问空指针的分段错误情况吗?@sergeyrar:分段错误是未定义行为的友好形式。调试器将立即向程序员指出问题所在。有些系统在空指针解引用时不会崩溃,这使得调试变得更加困难。那么如何修复此源代码以使其正常运行呢?