1

私は一般的なクイックソート機能を持っています:

void qsort(void* sup,int n,
 int(*cmp) (void *x,void *y),
  void (*swap) (void *a,void *b))
{
 int pv=n/2,l=0,h=n-1;

 if(n<2)
  return;

 while(h-1>=l)
 {
  if(l==pv)
  {
   swap(sup+pv,sup+pv+1);
   pv++;
  }
  if(h==pv)
  {
   swap(sup+pv,sup+(pv-1));
   pv--;
  }
  if(cmp(sup+h, sup+pv))
  {
   h--;
   continue;
  }
  if(cmp(sup+pv, sup+l))
  {
   l++;
   continue;
  }
  swap(sup+l,sup+h);
  l++,h--;
 }
 qsort(sup, l, cmp, swap);
 qsort(sup+l,n-l, cmp, swap);
}

これらの関数をパラメータとして:

int cmp(int *c1, int *c2) {
 return *c1 > *c2;
}

void swap(int *a,int *b)
{
 int c= *a;
 *a=*b;
 *b=c;
}

主な機能は次のとおりです。

int main()
{
 int arr[4] = {3,4,1,2};
 print(arr, 4);
 printf("\n\n");
 qsort(arr, 4, &cmp, &swap);
 print(arr, 4);
 return 0;
}

ここで、印刷は次のとおりです。

void print(int* arr, int size) {
 int i = 0;
 for(; i < size; ++i) {
  printf("%d \t", arr[i]);
 }
}

問題:

のプロトタイプが次の場合qsort:

void qsort(int* sup,int n,
 int(*cmp) (void *x,void *y),
  void (*swap) (void *a,void *b))

それはうまく機能し、

しかし、supパラメータを次のように変更するとvoid*:

void qsort(void* sup,int n,
 int(*cmp) (void *x,void *y),
  void (*swap) (void *a,void *b))

うまくいきません。誰にも理由はありますか?

私は、MinGW を使用して、Windows で Code::Blocks を使用しています。

4

3 に答える 3

0

パラメータを逆参照できる必要があります。void*コンパイラは渡された型を判別できないため、逆参照できません。を渡す場合は、明示的なキャストを使用する必要がありますvoid*

これ

void qsort(int* sup,int n,
 int(*cmp) (void *x,void *y),
  void (*swap) (void *a,void *b))

まったく問題ありませんが、ここでは

void qsort(void* sup,int n,
 int(*cmp) (void *x,void *y),
  void (*swap) (void *a,void *b))

(sup)を渡していますがvoid*、これは逆参照できません。したがって、最初のソリューションは問題ありませんが、型キャストする(*cmp)か、すべての型に対して qsort を定義する必要があります。

于 2013-04-06T21:02:14.700 に答える
0

並べ替えを修正する方法は次のとおりです。

#include <stdio.h>

void Qsort(
  void* sup,
  int n,
  int size,
  int(*cmp) (const void *x, const void *y),
  void (*swap) (void *a,void *b))
{
  int pv = n / 2, l = 0, h = n - 1;

  if (n < 2)
    return;

  while (h - 1 >= l)
  {
    if (l == pv)
    {
      swap((char*)sup + pv * size, (char*)sup + (pv + 1) * size);
      pv++;
    }

    if(h == pv)
    {
      swap((char*)sup + pv * size, (char*)sup + (pv - 1) * size);
      pv--;
    }

    if (cmp((char*)sup + h * size, (char*)sup + pv * size) > 0)
    {
      h--;
      continue;
    }

    if (cmp((char*)sup + pv * size, (char*)sup + l * size) > 0)
    {
      l++;
      continue;
    }

    swap((char*)sup + l * size, (char*)sup + h * size);
    l++, h--;
  }

  Qsort(sup, l, size, cmp, swap);
  Qsort((char*)sup + l * size, n - l, size, cmp, swap);
}

int cmp(const void *c1, const void *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 *c1, void *c2)
{
  int c = *(int*)c1;
  *(int*)c1 = *(int*)c2;
  *(int*)c2 = c;
}

void print(int* arr, int size)
{
  int i = 0;
  for(; i < size; ++i)
  {
    printf("%d \t", arr[i]);
  }
}

int main(void)
{
  int arr[4] = {3,4,1,2};
  print(arr, 4);
  printf("\n\n");
  Qsort(arr, 4, sizeof(arr[0]), &cmp, &swap);
  print(arr, 4);
  return 0;
}

出力 ( ideone ):

3       4       1       2

1       2       3       4

関数に標準ライブラリ関数と同じ名前を付けるのは良くないことに注意してください。プログラムがコンパイルまたは動作しない可能性があります。このため、 に変更qsortしましたQsort

于 2013-04-06T22:26:27.867 に答える