Generic quicksort因某些原因无法正常工作

时间:2016-04-25 12:49:32

标签: c generic-programming

我正在尝试制作一个通用的快速排序功能,但我无法理解我正在做的事情有什么问题,因为它无法正常工作。
这是我的代码:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>

typedef bool (*CmpFunction)(void*, void*);

    int cmp(const void *c1, const void *c2)
{
    assert(c1 && c2);
  int a = *(const int*)c1;
  int b = *(const int*)c2;
  if (a > b) return 1;
  if (a < b) return -1;
  return 0;
}

void swap(void *a, void *b, size_t size) {
    char tmp[size];

    memcpy(tmp, a, size);
    memcpy(a, b, size);
    memcpy(b, tmp, size);
}

   void quick_sort(void* a, int n, int size, CmpFunction cmp)
{
   int b = 1, t = n - 1;
   if (n < 2)
      return;
   swap((char*)a, (char*)a+(n/2)*size, size);
   char p = *(char*)a;
   while(b <= t) {
      while(t >= b && cmp((char*)a + t*size, &p) >= 0)
         t--;
      while(b <= t && cmp((char*)a + b*size, &p) < 0)
         b++;
      if (b < t)
         swap((char*)a+size*(b++), (char*)a+size*(t--), size);
   }
   swap((char*)a, (char*)a+t*size, size);
   quick_sort(a, t, size, cmp);
   n=n-t-1;
   quick_sort((char*)a + (t + 1)*size, n, size, cmp);
}

虽然原始的快速排序功能,但没有我试图使其通用是:

void quick_sort(int a[], int n)
{
   int p, b = 1, t = n - 1;
   if (n < 2)
      return;
   swap(&a[0], &a[n/2]);
   p = a[0];
   while(b <= t) {
      while(t >= b && a[t] >= p )
         t--;
      while(b <= t && a[b] < p)
         b++; 
      if ( b < t) 
         swap(&a[b++], &a[t--]);
   }
   swap(&a[0], &a[t]);
   quick_sort(a, t);
   n=n-t-1;
   quick_sort(a + t + 1, n);
}

void swap(int *c1, int *c2)
    {
      int c = *c1;
      *c1 = *c2;
      *c2 = c;
    }

我正在使用这个main():

    int main(){

    char b[] = {'a','t','b','c','y','s'};
    int c[] = {1,4,6,3,5,7};
    quick_sort(c, 6, sizeof(c[0]), &cmp);

    for (int i=0;i<6;i++)
        printf("%d | ", c[i]);

    return 0;
}

现在我们都同意输出应该是:

1, 3, 4, 5, 6, 7

这确实是我在运行NOT泛型函数时得到的 当我运行我的通用(上层)功能时,我得到了这个:

5 | 1 | 4 | 7 | 6 | 3 | 


你们有什么想法我错了吗? :)

1 个答案:

答案 0 :(得分:-1)

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


int integerCompare(const void *c1, const void *c2) // use this to compare int
{
    int a = *(const int*) c1;
    int b = *(const int*) c2;
    if (a > b) {
        return 1;
    } else if(a < b) {
        return -1;
    } else {
        return 0;
    }
}


int characterCompare(const void *c1, const void *c2) // use this to compare char
{
    char a = *(const int*) c1;
    char b = *(const int*) c2;
    if (a > b) {
        return 1;
    } else if(a < b) {
        return -1;
    } else {
        return 0;
    }
}



void swap(void *a, void *b, size_t size) {
    // instead of using an array, use a void pointer and malloc 
    void* tmp = malloc(size);
    memcpy(tmp, a, size);
    memcpy(a, b, size);
    memcpy(b, tmp, size);
    free(tmp); // free the allocated space
}

void quick_sort(void* a, int n, int size, int (*cmp)(const void*, const void*))
{
    int b = 1;
    int t = n - 1;
    if (n < 2) {
        return;
    }
    swap(a, a + (n/2) * size, size); // &a[0] == a
    // you do not need that p variable .. its value is not being modified
    while(b <= t) {
      while(t >= b && cmp(a + t*size, a) >= 0)
         t--;
      while(b <= t && cmp(a + b*size, a) < 0)
         b++;
      if (b < t)
         swap(a + size * (b++), a + size * (t--), size);
   }
   swap(a, a + t * size, size);
   quick_sort(a, t, size, cmp);
   n= n - t - 1;
   quick_sort(a + (t + 1)*size, n, size, cmp);
}

int main()
{
    char b[] = {'a','t','b','c','y','s'};
    int c[]  = {1,4,6,3,5,7};

    quick_sort(c, 6, sizeof(c[0]), &integerCompare);
    for (int i=0;i<6;i++) {
        printf("%d | ", c[i]);
    }
    printf("\n");
    quick_sort(b, 6, sizeof(b[0]), &characterCompare);
    for (int i=0;i<6;i++) {
        printf("%c  | ", b[i]);
    }

    return 0;
}