#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define EPS 1E-6

int compare_newdouble(const void *left, const void *right);
void mergesort(void *base, size_t n, size_t size, int (*compar)(const void *, const void *));



int compare_newdouble(const void *left, const void *right)
{
    double *p = (double*)left;
    double *q = (double*)right;
    
    if(fabs(fabs(*p) - fabs(*q)) < EPS)
    {
        return 0;
    }
    
    if(fabs(*p) > fabs(*q))
    {
        return 1;
    }
    
    return -1;
}

void mergesort(void *base, size_t n, size_t size, int (*compar)(const void *, const void *))
{
    const size_t mid = n/2;
    size_t l = 0, r = 0, a = 0;
    size_t i;
    void *add=malloc(size*n);
    
    if(n < 2)
    {
        return;
    }
    
    mergesort(base, mid, size, compar); //left array
    mergesort(base+size*mid, n-mid, size, compar); //right array
    
    while(l < mid && r < (n-mid))
    {
        if((*compar)(base+size*l, base+size*mid+size*r) == -1)
        {
            memcpy((add+size*a), (base+size*l), size); // putting the memory from left to add
            a++;
            l++;
        }
        else
        {
            memcpy((add+size*a), (base+size*mid+size*r), size); // putting the memory from right to add
            a++;
            r++;
        }
    }
    
    // Здесь были циклы
    
    if(l < mid)
    {
        memcpy((add+size*a), (base+size*l), size * (mid - l));
    }
    else if(r < (n-mid))
    {
        memcpy((add+size*a), (base+size*mid+size*r), size * (n-mid - r));

    }
    
    memcpy(base, add, size*n);
    
    free(add);
}

int main(void)
{
    int n = 15, i;
    double *a;
    
    a=malloc(sizeof(double)*n);
    
    for(i = 0; i < n; i++)
    {
        a[i] = n - i;
    }
    
    mergesort(a, n, sizeof(double), &compare_newdouble);
    
    for(i = 0; i < n; i++)
    {
        printf("%lf ", a[i]);
    }
    
    free(a);
    
    return 0;
}
