C 链表的合并排序
我有一个用于无序链表的Mergesort源代码,如下所示。假设我已经完成了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;
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->next如果
为空,则code>具有未定义的行为c->next->next
b=b->next->next如果
为空,则code>具有未定义的行为b->next
- 列表在
之前没有正确分割,而且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:分段错误是未定义行为的友好形式。调试器将立即向程序员指出问题所在。有些系统在空指针解引用时不会崩溃,这使得调试变得更加困难。那么如何修复此源代码以使其正常运行呢?