|
[ 簡単な説明 ] 各種のソート用関数、昇順⇔降順のデータ入替え関数、および文字列配列のダイナミックアロケーション用関数を定義しています。 各ソート用関数は、配列名とサイズを引数として与えると、昇順にソーティングします。 但し、逆写像ソート、および分布数えソートは、データの分布範囲( max、min )も引数として与える必要があります。 また、ラディックスソートは文字列長を引数として加えます。 間接ソート系の関数は、引数に int 型配列名を加えて指定すると、データ配列要素のソーティング後の並び順が指定した int 型配列に入れて返されます。 昇順⇔降順のデータ入替え関数は、配列名とサイズを引数として与えると、その配列要素の順番を入替えます。 無条件に入替えますので、同一配列およびサイズで2回続けて呼び出すと、元の配列に戻ります。 文字列配列のダイナミックアロケーション用関数は、('\0' を除く)要素数と最大文字列長を与えるとその配列のポインタを返します。 |
| クイックソート | qsort_i( ) qsort_d( ) qsort_c( ) |
逆写像ソート | mapsort( ) | |
| バブルソート | bsort_i( ) bsort_d( ) bsort_c( ) |
分布数えソート | distsort_i( ) distsort_d( ) |
|
| 挿入ソート | inssort_i( ) inssort_d( ) inssort_c( ) |
ラディックスソート | radsort( ) | |
| 選択ソート | ssort_i( ) ssort_d( ) ssort_c( ) |
間接クイックソート | iqsort_i( ) iqsort_d( ) iqsort_c( ) |
|
| マージソート | msort_i( ) msort_d( ) msort_c( ) |
間接分布数えソート | idistsort( ) | |
| ヒープソート | hsort_i( ) hsort_d( ) hsort_c( ) |
| void inv_i( ) |
| void inv_d( ) |
| void inv_c( ) |
| uchar **salloc( ) |
/* sort1.c sort subroutine source file */
/*#define DEBUG
#include <stdio.h>
#include <stdlib.h>
#include "sort.h"
uchar **salloc(int n, int len)
{
uchar **s, **p;
uchar *c;
static int i;
s = (uchar **)malloc(sizeof(uchar *) * n);
if(s == NULL)
{
fprintf(stderr, "Error : out of memory in salloc()\n");
return NULL;
}
for(i = 0, p = s; i < n; i++)
{
c = (uchar *)malloc(sizeof(uchar) * (len + 1));
if(c == NULL)
{
fprintf(stderr, "Error : out of memory in salloc()\n");
return NULL;
}
*p++ = c;
}
return s;
}
int strcomp(uchar *a, uchar *b)
{
uchar *p, *q;
p = a;
q = b;
while(*p)
{
if(*p > *q) return 1;
if(*p++ < *q++) return -1;
}
if(*q) return -1;
return 0;
}
void qsort_i(int a[], int n)
{
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in qsort_i()\n");
return;
}
subquick_i(a, a + n - 1);
}
void subquick_i(int *first, int *last)
{
int w;
int *i, *j, *p;
int x, t;
if((w = last - first) < 11) inssort_i(first, w + 1);
else
{
x = *(first + (int)((last - first) / 2));
i = first;
j = last;
do
{
while(x > *i) i++;
while(*j > x) j--;
if(i > j) break;
t = *i;
*i++ = *j;
*j-- = t;
} while(i <= j);
if(i - 1 > first) subquick_i(first, i - 1);
if(j + 1 < last) subquick_i(j + 1, last);
}
}
void qsort_d(double a[], int n)
{
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in qsort_d()\n");
return;
}
subquick_d(a, a + n - 1);
}
void subquick_d(double *first, double *last)
{
int w;
double *i, *j, *p;
double x, t;
if((w = last - first) < 11) inssort_d(first, w + 1);
else
{
x = *(first + (int)((last - first) / 2));
i = first;
j = last;
do
{
while(x > *i) i++;
while(*j > x) j--;
if(i > j) break;
t = *i;
*i++ = *j;
*j-- = t;
} while(i <= j);
if(i - 1 > first) subquick_d(first, i - 1);
if(j + 1 < last) subquick_d(j + 1, last);
}
}
void qsort_c(uchar *a[], int n)
{
uchar **i, **j, **l, **r;
uchar **st1[32], **st2[32], ***s1, ***s2;
uchar *x, *w;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in qsort_c()\n");
return;
}
s1 = st1;
s2 = st2;
*s1 = a;
*s2 = a + n - 1;
do
{
l = *s1--;
r = *s2--;
if(r - l < 11) inssort_c(l, r - l + 1);
else
{
do
{
i = l;
j = r;
x = *(l + (int)((r - l) / 2));
do
{
while(strcomp(x, *i) > 0) i++;
while(strcomp(*j, x) > 0) j--;
if(i > j) break;
w = *i;
*i++ = *j;
*j-- = w;
} while(i <= j);
if(j - l < r - i)
{
if(i < r)
{
*(++s1) = i;
*(++s2) = r;
}
r = j;
}
else
{
if(l < j)
{
*(++s1) = l;
*(++s2) = j;
}
l = i;
}
} while(l < r);
}
}while (s1 >= st1);
return;
}
void bsort_i(int a[], int n)
{
int x;
int h, i, j;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in bsort_i()\n");
return;
}
h = n - 1;
do
{
j = -1;
for(i = 1; i <= h; i++)
{
if(a[i - 1] > a[i])
{
j = i - 1;
x = a[j];
a[j] = a[i];
a[i] = x;
}
}
h = j;
} while(h >= 0);
}
void bsort_d(double a[], int n)
{
double x;
int h, i, j;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in bsort_d()\n");
return;
}
h = n - 1;
do
{
j = -1;
for(i = 1; i <= h; i++)
{
if(a[i - 1] > a[i])
{
j = i - 1;
x = a[j];
a[j] = a[i];
a[i] = x;
}
}
h = j;
} while(h >= 0);
}
void bsort_c(uchar *a[], int n)
{
uchar *x;
int h, i, j;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in bsort_c()\n");
return;
}
h = n - 1;
do
{
j = -1;
for(i = 1; i <= h; i++)
{
if(strcomp(*(a + i - 1), *(a + i)) > 0)
{
j = i - 1;
x = a[j];
a[j] = a[i];
a[i] = x;
}
}
h = j;
} while(h >= 0);
}
void inssort_i(int a[], int n)
{
int x;
int i, j;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in inssort_i()\n");
return;
}
for(i = 1; i < n; i++)
{
x = a[i];
j = i - 1;
while(j >= 0 && a[j] > x)
{
a[j + 1] = a[j];
j--;
}
a[j + 1] = x;
}
}
void inssort_d(double a[], int n)
{
double x;
int i, j;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in inssort_d()\n");
return;
}
for(i = 1; i < n; i++)
{
x = a[i];
j = i - 1;
while(j >= 0 && a[j] > x)
{
a[j + 1] = a[j];
j--;
}
a[j + 1] = x;
}
}
void inssort_c(uchar *a[], int n)
{
uchar *x;
int i, j;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in inssort_c()\n");
return;
}
for(i = 1; i < n; i++)
{
x = a[i];
j = i - 1;
while(j >= 0 && strcomp(a[j], x) > 0)
{
a[j + 1] = a[j];
j--;
}
a[j + 1] = x;
}
}
void ssort_i(int a[], int n)
{
int min;
int *ak, *alast, *p, *q;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in ssort_i()\n");
return;
}
alast = (p = a) + n - 1;
while(p < alast)
{
min = *(ak = q = p);
while(++q <= alast) if(*q < min) min = *(ak = q);
min = *ak;
*ak = *p;
*p++ = min;
}
}
void ssort_d(double a[], int n)
{
double min;
double *ak, *alast, *p, *q;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in ssort_d()\n");
return;
}
alast = (p = a) + n - 1;
while(p < alast)
{
min = *(ak = q = p);
while(++q <= alast) if(*q < min) min = *(ak = q);
min = *ak;
*ak = *p;
*p++ = min;
}
}
void ssort_c(uchar *a[], int n)
{
uchar *min;
uchar **ak, **alast, **p, **q;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in ssort_c()\n");
return;
}
alast = (p = a) + n - 1;
while(p < alast)
{
min = *(ak = q = p);
while(++q <= alast) if(strcomp(*q, min) < 0) min = *(ak = q);
min = *ak;
*ak = *p;
*p++ = min;
}
}
void msort_i(int a[], int n)
{
int *work;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in msort_i()\n");
return;
}
work = (int *)malloc(sizeof(int) * (int)(n / 2 + 1));
if(work == NULL)
{
fprintf(stderr, "out of memory in msort_i()\n");
return;
}
submerge_i(work, a, a + n - 1);
free((uchar *)work);
}
void submerge_i(int *work, int *afirst, int *alast)
{
int n;
int *ak, *ap, *amiddle, *w, *wp;
if((n = alast - afirst) < 11) inssort_i(afirst, n + 1);
else
{
amiddle = afirst + (int)(n / 2);
submerge_i(work, afirst, amiddle);
submerge_i(work, amiddle + 1, alast);
ak = ap = afirst;
w = wp = work;
while(ap <= amiddle) *w++ = *ap++;
while(ap <= alast && wp < w)
if(*wp <= *ap) *ak++ = *wp++;
else *ak++ = *ap++;
while(wp < w) *ak++ = *wp++;
}
}
void msort_d(double a[], int n)
{
double *work;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in msort_d()\n");
return;
}
work = (double *)malloc(sizeof(double) * (int)(n / 2 + 1));
if(work == NULL)
{
fprintf(stderr, "out of memory in msort_d()\n");
return;
}
submerge_d(work, a, a + n - 1);
free((uchar *)work);
}
void submerge_d(double *work, double *afirst, double *alast)
{
int n;
double *ak, *ap, *amiddle, *w, *wp;
if((n = alast - afirst) < 11) inssort_d(afirst, n + 1);
else
{
amiddle = afirst + (int)(n / 2);
submerge_d(work, afirst, amiddle);
submerge_d(work, amiddle + 1, alast);
ak = ap = afirst;
w = wp = work;
while(ap <= amiddle) *w++ = *ap++;
while(ap <= alast && wp < w)
if(*wp <= *ap) *ak++ = *wp++;
else *ak++ = *ap++;
while(wp < w) *ak++ = *wp++;
}
}
void msort_c(uchar *a[], int n, int len)
{
uchar **work;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in msort_c()\n");
return;
}
work = salloc((int)(n / 2 + 1), len);
if(work == NULL)
{
fprintf(stderr, "out of memory in msort_c()\n");
return;
}
submerge_c(work, a, a + n - 1);
free((uchar *)work);
}
void submerge_c(uchar **work, uchar **afirst, uchar **alast)
{
int n;
uchar **ak, **ap, **amiddle, **w, **wp;
if((n = alast - afirst) < 11) inssort_c(afirst, n + 1);
else
{
amiddle = afirst + (int)(n / 2);
submerge_c(work, afirst, amiddle);
submerge_c(work, amiddle + 1, alast);
ak = ap = afirst;
w = wp = work;
while(ap <= amiddle) *w++ = *ap++;
while(ap <= alast && wp < w)
if(strcomp(*wp, *ap) <= 0) *ak++ = *wp++;
else *ak++ = *ap++;
while(wp < w) *ak++ = *wp++;
}
}
void hsort_i(int a[], int n)
{
int j, k;
int *alast, *pi, *pj, x;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in hsort_i()\n");
return;
}
alast = a + n - 1;
for(k = n / 2; k >= 1; k--)
{
x = *(pi = a + (j = k) - 1);
while((j *= 2) < n)
{
pj = a + j - 1;
if(pj < alast && *pj < *(pj + 1)) pj++;
j = pj - a + 1;
if(x >= *pj) break;
*pi = *pj;
pi = pj;
}
*pi = x;
}
while(n > 0)
{
x = *alast;
*alast = *a;
alast = (pi = a) + (--n) - (j = 1);
while((j *= 2) <= n)
{
pj = a + j - 1;
if(pj < alast && *pj < *(pj + 1)) pj++;
j = pj - a + 1;
if(x >= *pj) break;
*pi = *pj;
pi = pj;
}
*pi = x;
}
}
void hsort_d(double a[], int n)
{
int j, k;
double *alast, *pi, *pj, x;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in hsort_d()\n");
return;
}
alast = a + n - 1;
for(k = n / 2; k >= 1; k--)
{
x = *(pi = a + (j = k) - 1);
while((j *= 2) < n)
{
pj = a + j - 1;
if(pj < alast && *pj < *(pj + 1)) pj++;
j = pj - a + 1;
if(x >= *pj) break;
*pi = *pj;
pi = pj;
}
*pi = x;
}
while(n > 0)
{
x = *alast;
*alast = *a;
alast = (pi = a) + (--n) - (j = 1);
while((j *= 2) <= n)
{
pj = a + j - 1;
if(pj < alast && *pj < *(pj + 1)) pj++;
j = pj - a + 1;
if(x >= *pj) break;
*pi = *pj;
pi = pj;
}
*pi = x;
}
}
void hsort_c(uchar *a[], int n)
{
int j, k;
uchar **alast, **pi, **pj, *x;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in hsort_c()\n");
return;
}
alast = a + n - 1;
for(k = n / 2; k >= 1; k--)
{
x = *(pi = a + (j = k) - 1);
while((j *= 2) < n)
{
pj = a + j - 1;
if(pj < alast && strcomp(*pj, *(pj + 1)) < 0) pj++;
j = pj - a + 1;
if(strcomp(x, *pj) >= 0) break;
*pi = *pj;
pi = pj;
}
*pi = x;
}
while(n > 0)
{
x = *alast;
*alast = *a;
alast = (pi = a) + (--n) - (j = 1);
while((j *= 2) <= n)
{
pj = a + j - 1;
if(pj < alast && strcomp(*pj, *(pj + 1)) < 0) pj++;
j = pj - a + 1;
if(strcomp(x, *pj) >= 0) break;
*pi = *pj;
pi = pj;
}
*pi = x;
}
}
void mapsort(int a[], int n, int max, int min)
{
int i, j;
int *index, *lindex, *next, *p, *q, *r, x;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in mapsort()\n");
return;
}
index = (int *)malloc(sizeof(int) * (max - min + 1));
next = (int *)malloc(sizeof(int) * n);
if(index == NULL || next == NULL)
{
fprintf(stderr, "Error : out of memory in mapsort()\n");
return;
}
lindex = p = index + max - min;
while(p >= index) *p-- = -1;
p = a + (i = n - 1);
q = next + i;
while(p >= a)
{
*q-- = *(r = index + (x = *p-- - min));
*r = i--;
}
for(x = min, p = a, q = index; q <= lindex; x++)
{
i = *q++;
while(i >= 0)
{
*p++ = x;
i = *(next + i);
}
}
free((uchar *)next);
free((uchar *)index);
}
void distsort_i(int a[], int n, int max, int min)
{
int m;
int *b, *count, *p, *pp, *q;
int *clast, *r;
if(n <= 1 || max <= min)
{
fprintf(stderr, "Error : illegal data input in distsort_i()\n");
if(n <= 1) fprintf(stderr, " n=%d (n > 2)\n", n);
if(max <= min)
fprintf(stderr, " max=%d, min=%d (max > min)\n", max, min);
return;
}
b = (int *)malloc(sizeof(int) * n);
count = (int *)malloc(sizeof(int) * ((m = max - min) + 1));
if(b == NULL || count == NULL)
{
fprintf(stderr, "Error : out of memory in distsort_i()\n");
return;
}
clast = r = count + m;
while(r >= count) *r-- = 0;
p = pp = b + n - 1;
q = a + n - 1;
while(q >= a) (*(count + (*p-- = *q-- - min)))++;
r = count;
while(++r <= clast) *r += *(r - 1);
while(pp >= b) *(a + --*(count + *pp)) = *pp-- + min;
free((uchar *)b);
free((uchar *)count);
}
void distsort_d(double a[], int n, double max, double min)
{
double *dp, *dq, *work, ratio;
int *b, *jun, *p, i, m;
if(n <= 1 || max <= min)
{
fprintf(stderr, "Error : illegal data input in distsort_d()\n");
if(n <= 1) fprintf(stderr, " n=%d (n > 2)\n", n);
if(max <= min)
fprintf(stderr, " max=%d, min=%d (max > min)\n", max, min);
return;
}
b = (int *)malloc(sizeof(int) * n);
jun = (int *)malloc(sizeof(int) * n);
work = (double *)malloc(sizeof(double) * n);
if(b == NULL || jun == NULL || work == NULL)
{
fprintf(stderr, "Error : out of memory in distsort_d()\n");
return;
}
m = n / 2;
ratio = (double)m / (max - min);
for(i = 0, dp = a, dq = work, p = b; i < n; i++)
*p++ = (int)(((*dq++ = *dp++) - min) * ratio);
idistsort(b, n, m, 0, jun);
for(i = 0, dp = a, p = jun; i < n; i++) *dp++ = *(work + *p++);
inssort_d(a, n);
free((uchar *)work);
free((uchar *)jun);
free((uchar *)b);
}
void radsort(uchar *a[], int n, int len)
{
int j;
int *count, *clast, *p, **index, **ilast, **pp;
uchar **alast, **pi, **pw, **wlast, **work;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in radsort()\n");
return;
}
work = salloc(n, len);
count = (int *)malloc(sizeof(int) * 256);
index = (int **)malloc(sizeof(int *) * n);
if(work == NULL || count == NULL || index == NULL)
{
fprintf(stderr, "Error : out of memory in radsort()\n");
return;
}
clast = count + 256;
ilast = index + n - 1;
alast = a + n;
wlast = work + n - 1;
for(j = len - 1, p = clast; j >= 0; j--)
{
while(--p >= count) *p = 0;
pi = alast;
pp = ilast;
pw = wlast;
while(--pi >= a) (*(*pp-- = count + *((*pw-- = *pi) + j)))++;
p++;
while(++p < clast) *p += *(p - 1);
pp = ilast;
pw = wlast;
while(pw >= work) *(a + --*(*pp--)) = *pw--;
}
free((uchar *)index);
free((uchar *)count);
free((uchar *)work);
}
void inv_i(int a[], int n)
{
int *p, *q, w;
q = (p = a) + n - 1;
while(p < q)
{
w = *p;
*p++ = *q;
*q-- = w;
}
}
void inv_d(double a[], int n)
{
double *p, *q, w;
q = (p = a) + n - 1;
while(p < q)
{
w = *p;
*p++ = *q;
*q-- = w;
}
}
void inv_c(uchar *a[], int n)
{
uchar **p, **q, *w;
q = (p = a) + n - 1;
while(p < q)
{
w = *p;
*p++ = *q;
*q-- = w;
}
}
void iqsort_i(int a[], int n, int jun[])
{
int *i, *j, *l, *r;
int *st1[32], *st2[32], **s1, **s2;
int x, w;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in iqsort_i()\n");
return;
}
for(w = 0, r = jun; w < n; ) *r++ = w++;
s1 = st1;
s2 = st2;
*s1 = jun;
*s2 = jun + n - 1;
do
{
l = *s1--;
r = *s2--;
do
{
i = l;
j = r;
x = *(a + *(l + ((int)(r - l) / 2)));
do
{
while(x > *(a + *i)) i++;
while(*(a + *j) > x) j--;
if(i > j) break;
w = *i;
*i++ = *j;
*j-- = w;
} while(i <= j);
if(j - l < r - i)
{
if(i < r)
{
*(++s1) = i;
*(++s2) = r;
}
r = j;
}
else
{
if(l < j)
{
*(++s1) = l;
*(++s2) = j;
}
l = i;
}
} while(l < r);
}while (s1 >= st1);
return;
}
void iqsort_d(double a[], int n, int jun[])
{
int *i, *j, *l, *r, k;
int *st1[32], *st2[32], **s1, **s2;
double x, w;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in iqsort_d()\n");
return;
}
for(k = 0, r = jun; k < n; ) *r++ = k++;
s1 = st1;
s2 = st2;
*s1 = jun;
*s2 = jun + n - 1;
do
{
l = *s1--;
r = *s2--;
do
{
i = l;
j = r;
x = *(a + *(l + ((int)(r - l) / 2)));
do
{
while(x > *(a + *i)) i++;
while(*(a + *j) > x) j--;
if(i > j) break;
w = *i;
*i++ = *j;
*j-- = w;
} while(i <= j);
if(j - l < r - i)
{
if(i < r)
{
*(++s1) = i;
*(++s2) = r;
}
r = j;
}
else
{
if(l < j)
{
*(++s1) = l;
*(++s2) = j;
}
l = i;
}
} while(l < r);
}while (s1 >= st1);
return;
}
void iqsort_c(uchar *a[], int n, int jun[])
{
int *i, *j, *l, *r, w;
int *st1[32], *st2[32], **s1, **s2;
uchar *x;
if(n <= 1)
{
fprintf(stderr, "Error : n <= 1 in iqsort_d()\n");
return;
}
for(w = 0, r = jun; w < n; ) *r++ = w++;
s1 = st1;
s2 = st2;
*s1 = jun;
*s2 = jun + n - 1;
do
{
l = *s1--;
r = *s2--;
do
{
i = l;
j = r;
x = *(a + *(l + ((int)(r - l) / 2)));
do
{
while(strcomp(x, *(a + *i)) > 0) i++;
while(strcomp(*(a + *j), x) > 0) j--;
if(i > j) break;
w = *i;
*i++ = *j;
*j-- = w;
} while(i <= j);
if(j - l < r - i)
{
if(i < r)
{
*(++s1) = i;
*(++s2) = r;
}
r = j;
}
else
{
if(l < j)
{
*(++s1) = l;
*(++s2) = j;
}
l = i;
}
} while(l < r);
}while (s1 >= st1);
return;
}
void idistsort(int a[], int n, int max, int min, int jun[])
{
int m;
int *b, *count, *p, *pp, *q;
int *clast, *r;
if(n <= 1 || max <= min)
{
fprintf(stderr, "Error : illegal data input in idistsort()\n");
if(n <= 1) fprintf(stderr, " n=%d (n > 2)\n", n);
if(max <= min)
fprintf(stderr, " max=%d, min=%d (max > min)\n", max, min);
return;
}
b = (int *)malloc(sizeof(int) * n);
count = (int *)malloc(sizeof(int) * ((m = max - min) + 1));
if(b == NULL || count == NULL)
{
fprintf(stderr, "Error : out of memory in idistsort()\n");
return;
}
clast = r = count + m;
while(r >= count) *r-- = 0;
p = pp = b + n - 1;
q = a + n - 1;
while(q >= a) (*(count + (*p-- = *q-- - min)))++;
r = count;
while(++r <= clast) *r += *(r - 1);
m = n - 1;
while(pp >= b) *(jun + --*(count + *pp--)) = m--;
free((uchar *)b);
free((uchar *)count);
}
|