Прежде всего вызов вашей функции mergesort
при включении stdlib.h
некорректен и должен вызывать ошибку с недавними компиляторами C.
Затем эта последовательность кода вызывает неопределенное поведение путем разыменования нулевого значения. указатель:
node *z = NULL;
node *c = z;
c->next = a; // UB!
В этот момент c равен NULL, поэтому вы не должны использовать c->next
. При обычной реализации C попытка записи в запрещенную память вызывает ошибку сегмента.
Ваш алгоритм пытается использовать sentinel , но ИМХО это нецелесообразное использование дело. Проще просто запомнить первое значение. И вы должны также обработать случай, когда вы достигнете конца одного из обоих отсортированных списков. Код может стать:
node *merge(node *a, node *b)
{
node *c = z; // current node initialized to null
node *top; // declare the future return value
do
{
if (a->key > b->key)
{
if (c == z) top = a; // if first value, remember it
else c->next = a; // else add the node to current list
c = a; a = a->next;
if (a == NULL) { // explicitely handle end of input list
c->next = b;
break;
}
}
else
{
if (c == z) top = b;
else c->next = b;
c = b; b = b->next;
if (b == NULL) {
c->next = a;
break;
}
}
} while (c != z);
return top;
}
Но это еще не все. Ваш код представляет собой смесь C и C ++. Вы используете только библиотечные функции C, но компилируете код с помощью компилятора C ++. Язык C не допускает перегрузок функций, поэтому не следует повторно использовать имя функции стандартной библиотеки с другим набором параметров (mergesort
). И на C языке вам не нужно приводить mallo c.
Даже с моим исправлением ваш код будет работать на любом приличном компиляторе C если вы не измените имя функции mergesort
. Вы были предупреждены.