算法记录:归并排序

来源:互联网 发布:文明5超级大国mod mac 编辑:程序博客网 时间:2024/05/22 05:15
好几天没写了,这次给出的是我最终成型的代码了,所以可能有点脏,排序的链表部分我会放到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);

}

 
原创粉丝点击