クイックソート メモ
いつもクイックソートの書き方がわからなくなる(セグフォとかで正確に実行できない)ことが多いので、メモとしてqsortのC言語によるアルゴリズムを書いておく。今回はCの標準ライブラリであるqsort関数とどちらが実行速度が大きいかを比較した。
#include <stdio.h> #include <stdlib.h> #include <time.h> void myqsort(int left, int right, int A[]) { if (left >= right) return; int i = left, j = right; // i = 0, j = n-1 // オーバーフロー対策でこのようにmiddleを求める int pivot = (j-i)/2+i; int val = A[pivot]; while(1) { // iとjが交わる時は1以下で収まる.交わったらすぐにwhileの条件を満たさなくなるから. while(A[i] < val) i++; while(A[j] > val) j--; if (i >= j) break; int tmp = A[i]; A[i] = A[j]; A[j] = tmp; i++; j--; } // A[i] はvalより大きいが,A[k]は任意のk (<= i-1)でvalより小さい myqsort(left, i-1, A); // A[i] はvalより小さいが,A[k]は任意のk (>= j+1)でvalより大きい myqsort(j+1, right, A); } // ライブラリのqsort関数で用いる比較関数 int cmpnum(const void *n1, const void *n2) { if (*(int*)n1 > *(int*)n2) { return 1; } else if (*(int*)n1 < *(int*)n2) { return -1; } else { return 0; } } int main() { int n = 10000; int B[n]; for (int i = 0; i < n; i++) { B[i] = rand() % 100000; } clock_t start = clock(); // 自作qsort関数 myqsort(0, n-1, B); clock_t end = clock(); printf("time = %f ", (double)(end - start)/CLOCKS_PER_SEC); for (int i = 0; i < n; i++) { B[i] = rand() % 100000; } size_t int_size = sizeof(int); clock_t start1 = clock(); // cの標準ライブラリを使用 qsort(B, n, int_size, cmpnum); clock_t end1 = clock(); printf("time = %f ", (double)(end1 - start1)/CLOCKS_PER_SEC); }
実行結果(単位 s)
myqsort | qsort |
---|---|
0.079998 | 0.160001 |
意外と自分で作ったqsortの方が早かった。