|
非再帰版のマージソートプログラムを作っています。再帰版のマージソート
はとても速いのですが、非再帰版が思うように速度が出ません。
データの個数が2^Nでなくても、奇数でもソートできるようにしたいの
でこのようなプログラムにしたのですが、効率が悪いのでしょうか?
コンパイラはBorland C++ 5.8.2です。
#pragma comment(lib, "winmm.lib")を付けるとVCでもコンパイルできる
と思います。
//
// 非再帰版マージソート(qsortとの時間比較付き)
//
// 考察: Nが大きくなればなるほどqsortとの差が開くが、これはデータキャッシュ・ミスによるものと思われる。
//
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define N 10000
int a[N], b[N], c[N]; /* 作業領域 */
int comp(const void *a, const void *b);
void qsort_sub(unsigned t);
int main(void)
{
int i, j, x, y, x1, y1, f, t;
DWORD t1;
t = (unsigned)time(NULL);
srand(t);
for (i = 0; i < N; i++)
a[i] = rand();
t1 = timeGetTime();
do {
/* 部分ランへの分割 */
x = y = f = 0; x1 = y1 = -1;
for (i = 0; i < N; i++)
if (f == 0) {
if (x1 <= a[i])
b[x++] = x1 = a[i];
else {
f = 1;
c[y++] = y1 = a[i];
}
} else /* f == 1 */ {
if (y1 <= a[i])
c[y++] = y1 = a[i];
else {
f = 0;
b[x++] = x1 = a[i];
}
}
/* 部分ランのマージ(配列の交換がなくなったら終了) */
x1 = y1 = j = f = 0;
for (i = 0; i < N; i++)
if (x1 == x) {
a[j++] = c[y1++];
if (f == 3);
else if (f == 1)
f = 3;
else
f = 2;
} else if (y1 == y) {
a[j++] = b[x1++];
if (f == 3);
else if (f == 2)
f = 3;
else
f = 1;
} else if (b[x1] <= c[y1]) {
a[j++] = b[x1++];
if (f == 3);
else if (f == 2)
f = 3;
else
f = 1;
} else { /* b[x1] > c[y1] */
a[j++] = c[y1++];
if (f == 3);
else if (f == 1)
f = 3;
else
f = 2;
}
/* ソート済みになったかチェック */
// f = 0;
// for (i = 0; i < N - 1; i++)
// if (a[i] > a[i + 1]) {
// f = 1;
// break;
// }
} while (f == 3);
// printf("a = ");
// for (i = 0; i < N; i++)
// printf("%d ", a[i]);
// putchar('\n');
printf("%u ms\n", timeGetTime() - t1);
qsort_sub(t);
return 0;
}
int comp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
void qsort_sub(unsigned t)
{
DWORD t1;
int i;
srand(t);
for (i = 0; i < N; i++)
a[i] = rand();
t1 = timeGetTime();
qsort(a, N, sizeof(int), comp);
printf("%u ms\n", timeGetTime() - t1);
}
|