好几天没写了,这次给出的是我最终成型的代码了,所以可能有点脏,排序的链表部分我会放到RavenX的List部分去做的,这个没办法跟数据结构抽离开的
先来个归并排序,这玩意思路其实很简单很简单的东西,就是针对比较次数来说
C[N] = 2*C[N/2] + N;这里把N待换成2^n带入,最终的比较次数是N*logN,也是个蛮经典的东西,Merge排序的一个好处是如果你存储是稳定的,那么它本身的效率也是稳定的,坏处就是占用相等的空间,所以内圈循环全跑到malloc上去了.
static void rx_merge_internal(void *arr, size_t l, size_t m, size_t r, size_t element_size, rx_cmp_func cmp_f, rx_swap_func swap_f, const rx_alloc *palloc)
{
size_t count = r - l + 1;
void *aux = NULL;
RX_ASSERT(arr != NULL && element_size > 0 && cmp_f != NULL && swap_f != 0);
RX_ASSERT(palloc != NULL && palloc->rx_alloc_f != NULL && palloc->rx_dealloc_f != NULL);
aux = palloc->rx_alloc_f(element_size * count);
if(aux == NULL)rx_fatal_error("memory overflow : rx_merge_internal/n");
{
size_t i = l, j = m + 1, k = 0;
for(; k < count; ++k)
{
if(i == m + 1)
{
swap_f(RX_GET_ELEM(arr,element_size, j++), RX_GET_ELEM(aux,element_size, k));
continue;
}
if(j == r + 1)
{
swap_f(RX_GET_ELEM(arr,element_size, i++), RX_GET_ELEM(aux,element_size, k));
continue;
}
if(cmp_f(RX_GET_ELEM(arr,element_size, i), RX_GET_ELEM(arr,element_size, j)) < 0)
{
swap_f(RX_GET_ELEM(arr,element_size, i++), RX_GET_ELEM(aux,element_size, k));
}else
{
swap_f(RX_GET_ELEM(arr,element_size, j++), RX_GET_ELEM(aux,element_size, k));
}
}
i = l;
for(k = 0; k < count; ++k)
{
swap_f(RX_GET_ELEM(arr,element_size, i++), RX_GET_ELEM(aux,element_size, k));
}
}
palloc->rx_dealloc_f(aux, element_size * count);
}
static void rx_merge_sort_internal(void *arr, size_t l, size_t r, size_t element_size, rx_cmp_func cmp_f, rx_swap_func swap_f, const rx_alloc *palloc)
{
size_t count = (r - l) + 1;
size_t m = (l + r)/2;
if(l >= r)return;
if(count < 20)
{
rx_insertion_sort(RX_GET_ELEM(arr, element_size, l), count, element_size, cmp_f, swap_f);
return;
}
rx_merge_sort_internal(arr, l, m, element_size, cmp_f, swap_f, palloc);
rx_merge_sort_internal(arr, m+1, r, element_size, cmp_f, swap_f, palloc);
rx_merge_internal(arr, l,m,r, element_size, cmp_f, swap_f, palloc);
}
void rx_merge_sort(void *arr, size_t count, size_t element_size, rx_cmp_func cmp_f, rx_swap_func swap_f, const rx_alloc *palloc)
{
RX_ASSERT(arr != NULL && count > 0 && element_size > 0 && cmp_f != NULL && swap_f != 0);
RX_ASSERT(palloc != NULL && palloc->rx_alloc_f != NULL && palloc->rx_dealloc_f != NULL);
rx_merge_sort_internal(arr, 0, count - 1, element_size, cmp_f, swap_f,palloc);
}
先来个归并排序,这玩意思路其实很简单很简单的东西,就是针对比较次数来说
C[N] = 2*C[N/2] + N;这里把N待换成2^n带入,最终的比较次数是N*logN,也是个蛮经典的东西,Merge排序的一个好处是如果你存储是稳定的,那么它本身的效率也是稳定的,坏处就是占用相等的空间,所以内圈循环全跑到malloc上去了.
static void rx_merge_internal(void *arr, size_t l, size_t m, size_t r, size_t element_size, rx_cmp_func cmp_f, rx_swap_func swap_f, const rx_alloc *palloc)
{
size_t count = r - l + 1;
void *aux = NULL;
RX_ASSERT(arr != NULL && element_size > 0 && cmp_f != NULL && swap_f != 0);
RX_ASSERT(palloc != NULL && palloc->rx_alloc_f != NULL && palloc->rx_dealloc_f != NULL);
aux = palloc->rx_alloc_f(element_size * count);
if(aux == NULL)rx_fatal_error("memory overflow : rx_merge_internal/n");
{
size_t i = l, j = m + 1, k = 0;
for(; k < count; ++k)
{
if(i == m + 1)
{
swap_f(RX_GET_ELEM(arr,element_size, j++), RX_GET_ELEM(aux,element_size, k));
continue;
}
if(j == r + 1)
{
swap_f(RX_GET_ELEM(arr,element_size, i++), RX_GET_ELEM(aux,element_size, k));
continue;
}
if(cmp_f(RX_GET_ELEM(arr,element_size, i), RX_GET_ELEM(arr,element_size, j)) < 0)
{
swap_f(RX_GET_ELEM(arr,element_size, i++), RX_GET_ELEM(aux,element_size, k));
}else
{
swap_f(RX_GET_ELEM(arr,element_size, j++), RX_GET_ELEM(aux,element_size, k));
}
}
i = l;
for(k = 0; k < count; ++k)
{
swap_f(RX_GET_ELEM(arr,element_size, i++), RX_GET_ELEM(aux,element_size, k));
}
}
palloc->rx_dealloc_f(aux, element_size * count);
}
static void rx_merge_sort_internal(void *arr, size_t l, size_t r, size_t element_size, rx_cmp_func cmp_f, rx_swap_func swap_f, const rx_alloc *palloc)
{
size_t count = (r - l) + 1;
size_t m = (l + r)/2;
if(l >= r)return;
if(count < 20)
{
rx_insertion_sort(RX_GET_ELEM(arr, element_size, l), count, element_size, cmp_f, swap_f);
return;
}
rx_merge_sort_internal(arr, l, m, element_size, cmp_f, swap_f, palloc);
rx_merge_sort_internal(arr, m+1, r, element_size, cmp_f, swap_f, palloc);
rx_merge_internal(arr, l,m,r, element_size, cmp_f, swap_f, palloc);
}
void rx_merge_sort(void *arr, size_t count, size_t element_size, rx_cmp_func cmp_f, rx_swap_func swap_f, const rx_alloc *palloc)
{
RX_ASSERT(arr != NULL && count > 0 && element_size > 0 && cmp_f != NULL && swap_f != 0);
RX_ASSERT(palloc != NULL && palloc->rx_alloc_f != NULL && palloc->rx_dealloc_f != NULL);
rx_merge_sort_internal(arr, 0, count - 1, element_size, cmp_f, swap_f,palloc);
}