模板化快速/合并排序

时间:2015-11-29 18:31:34

标签: c++ sorting templates quicksort

我一直在尝试用C ++编写模板化函数,它可以接受任何类型的数组并对其进行排序。使用的排序必须是快速排序或合并排序,但我在实现其中任何一个时遇到很多麻烦,因为快速排序标题通常带有top和bottom参数,并且合并排序带有第一个和最后一个参数我的函数头看起来像这样:void mySort(T * array,int n)

到目前为止,我有这个:

template <typename T>
void sort(T *a, int n)
{
  int i = 0;
  int j = n-1;
  int tmp;
  int pivot = a[(n-1)/2];
  while (i <= j){
    while (a[i] < pivot)
       i++;
    while (a[j] > pivot)
       j--;
    if (i<=j){
       tmp = a[i];
       a[i] = a[j];
       a[j] = a[i];
       i++;
       j--;
    }
  }

  if(0<j)
    sort(a, j);
  /*
  if(i<right)
    sort(
  */
}

我试图使用递归调用进行排序,但我无法弄清楚如何为创建的正确分区调用递归,而没有不同的参数列表。

2 个答案:

答案 0 :(得分:0)

在回答实际问题之前:您的代码将受益于将分区代码分解出函数体!这样,你基本上调用分区来确定要调用的两个数组之间的中点,即你有类似的东西:

template <typename T>
void sort(T* a, int n) {
    T* mid = partition(a, n);
    // ...
}

这个想法是[a, mid)包含排序小于数据透视表的所有元素,而[mid, a + n)包含排序等于或大于数据透视表的所有元素。剩下的就是

  1. 用两个数组递归调用sort(),即

    sort(a, mid - a);
    sort(mid, (a + n) - mid);
    
  2. 如果获得的数组小于2,请确保sort()终止。

  3. 当然,如果您希望快速排序快速,您还需要拉出六打左右的技巧。像:

    1. 使用Introsort确保复杂度为O(n lg n)(例如与合并排序一起使用)。
    2. 在小范围内使用插入排序。
    3. 使用分区和插入排序的实现,利用合适的标记。
    4. 直接对排序范围进行排序。
    5. 其中一个奇怪的事情就是选择一个支点。据我所知,使用中间元素以及任何更高级的技术(假设实现了上述优化)。

答案 1 :(得分:0)

将被调用函数与递归函数分开:

// recursive function
template <typename T>
void quicksort(T *a, int lo, int hi)
{
    // ...
}

// called function    
template <typename T>
void sort(T *a, int n)
{
    if(n < 2)return;
    quicksort(a, 0, n-1);
}