学校の宿題でC言語標準装備のクイックソートを作れというのがあった。
 仕様は void my_qsort(void *base, size_t num, size_t width, int (*compare)(char*,char*))であるがvoid型のポインタの処理が結構難しかった。

 スワップ関数

void my_swap(void *base, int x, int y, size_t width){
  char *temp = (char*)malloc(width);
  memcpy(temp,base+x*width,width);
  memcpy(base+x*width,base+y*width,width);
  memcpy(base+y*width,temp,width);
  free(temp);
}

 left番目からright番目までrightを基準値にして大小を分割する関数

int partition(void *base, size_t width, int left, int right, int (*compare)(char*, char*)){
  int i,j;
  i = left - 1;
  j = right;
  char *pivot = (char*)(base+right*width);
  while(1){
    while((*compare)((char*)(base+(++i)*width),pivot) < 0)
    ;
    while(i < j-- && (*compare)(pivot,(char*)(base+j*width)) < 0)
    ;
    if(i >= j)
      break;
    my_swap(base,i,j,width);
  }
  my_swap(base,i,right,width);
  return i;
}

クイックソート本体

void my_qsort(void *base, size_t num, size_t width, int (*compare)(char*, char*)){
  int right,left,mid,sp;
  int low[STACK_SIZE], high[STACK_SIZE];
  low[0] = 0;
  high[0] = num - 1;
  sp = 1;
  while(sp > 0){
    sp--;
    left = low[sp];
    right = high[sp];
    if(left > right)
    ;
    else{
      mid = partition(base,width,left,right,compare);
      if(mid - left < right - mid){
        low[sp] = mid +1;
        high[sp++] = right;
        low[sp] = left;
        high[sp++] = mid - 1;
      } else{
        low[sp] = left;
        high[sp++] = mid - 1;
        low[sp] = mid + 1;
        high[sp++] = right;
      }
    }
  }
}