[ 簡単な説明 ] 非ソートのデータ配列中から、昇順に数えた場合の該当ランキングデータを抽出する関数です。 アルゴリズムはクイックソートを使用していますが、ソートするわけではないので、スタックは不要です。 各関数は、引数として、配列名、配列サイズ、ランキングを与えます。戻り値が該当データです。 |
int rank_i( ) |
double rank_d( ) |
uchar *rank_c( ) |
/* sort3.c 選択(n個のデータの k+1 番目を抽出する) */ #include <stdio.h> #include <stdlib.h> #include "sort.h" int rank_i(int aa[], int n, int k) { int *a, *ak, *i, *j, *left, *right, x, t; a = (int *)malloc(n * sizeof(int)); if(a == NULL) { fprintf(stderr, "Error : out of memory in rank_i()\n"); return -1; } i = a + n - 1; j = aa + n - 1; while(i >= a) *i-- = *j--; right = (left = a) + n - 1; ak = a + k; do { x = *ak; i = left; j = right; for( ; ; ) { while(*i < x) i++; while(x < *j) j--; if(i > j) break; t = *i; *i++ = *j; *j-- = t; } if(j < ak) left = i; if(ak < i) right = j; } while(left < right); free(a); return *ak; } double rank_d(double aa[], int n, int k) { double *a, x, t; int i, j, left, right; a = (double *)malloc(n * sizeof(double)); if(a == NULL) { fprintf(stderr, "Error : out of memory in rank_d()\n"); return -1; } for(i = 0; i < n; i++) a[i] = aa[i]; left = 0; right = n - 1; do { x = a[k]; i = left; j = right; for( ; ; ) { while(a[i] < x) i++; while(x < a[j]) j--; if(i > j) break; t = a[i]; a[i++] = a[j]; a[j--] = t; } if(j < k) left = i; if(k < i) right = j; } while(left < right); x = a[k]; free(a); return x; } uchar *rank_c(uchar *aa[], int n, int k) { uchar **a, **ak, **i, **j, **left, **right, *x, *t; a = (uchar **)malloc(n * sizeof(uchar *)); if(a == NULL) { fprintf(stderr, "Error : out of memory in rank_c()\n"); return NULL; } i = a + n - 1; j = aa + n - 1; while(i >= a) { x = *i-- = (uchar *) malloc((strlen(*j) + 1) * sizeof(uchar)); if(x == NULL) { fprintf(stderr, "Error : out of memory in rank_c()\n"); return NULL; } t = *j--; while((*x++ = *t++) != '\0') ; } right = (left = a) + n - 1; ak = a + k; do { x = *ak; i = left; j = right; for( ; ; ) { while(strcmp(*i, x) < 0) i++; while(strcmp(x, *j) < 0) j--; if(i > j) break; t = *i; *i++ = *j; *j-- = t; } if(j < ak) left = i; if(ak < i) right = j; } while(left < right); i = a + n - 1; while(i >= a) free(i--); free(a); return *ak; } |