我正在使用在线C ++编译器遇到分段错误,而整天做这个单一函数mergesort并且找不到它可能的位置。另一个问题是,我不理解这种查找链表中间的方法,为什么是赋值运算符,有没有更好的方法呢?任何帮助将不胜感激。
#include <stdio.h>
#include <stdlib.h>
struct listnode { struct listnode * next; int key; };
struct listnode * sort(struct listnode * a)
{
struct listnode *fast, *slow, *mid, *left, *right;
fast = a; left = a; right = NULL; mid = NULL;
//data is null or one node
if (!a || !a->next)
{
return a;
}
//find mid by declaring a pointer skipping throw an extra node for each loop
while (fast)
{
if (fast = fast->next) { fast = fast->next; }
mid = slow;
slow = slow->next;
}
//split the list in recursion
if (mid != NULL) { mid->next = NULL; }
a = sort(a); slow = sort(slow);
//merge
while (left != NULL && slow != NULL)
{
if (left->key < right->key) { left->next = mid; right = left; }
else
{
if (!right)
a = slow;
else
{
right = slow; right->next = slow; slow = slow->next; right->next = left;
}
}
}
if (left == NULL) { right->next = slow; }
return(a);
}
//test
int main()
{
long i;
struct listnode *node, *tmpnode, *space;
space = (struct listnode *) malloc(500000 * sizeof(struct listnode));
for (i = 0; i< 500000; i++)
{
(space + i)->key = 2 * ((17 * i) % 500000);
(space + i)->next = space + (i + 1);
}
(space + 499999)->next = NULL;
node = space;
printf("\n prepared list, now starting sort\n");
node = sort(node);
printf("\n checking sorted list\n");
for (i = 0; i < 500000; i++)
{
if (node == NULL)
{
printf("List ended early\n"); exit(0);
}
if (node->key != 2 * i)
{
printf("Node contains wrong value\n"); exit(0);
}
node = node->next;
}
printf("Sort successful\n");
exit(0);
}
答案 0 :(得分:3)
至少有一个问题是:
while (fast)
{
if (fast = fast->next) { fast = fast->next; }
mid = slow;
slow = slow->next; // <-------- HERE!
}
在此循环之前, fast
被指定为非空值,因此控件进入循环并尝试读取slow->next
,这是无效的。 slow
指针未在循环之前分配给任何内容,因此它保存垃圾值并且不指向有效的内存位置。因此,通过该指针读取存储器很可能违反进程地址空间。从语言的角度来看,读取未初始化的指针是undefined behavior的一个例子。
另请参阅this问题中的一个很好的解释。