1 : // ソートテスト その1 2 : #include <stdio.h> 3 : #include <stdlib.h> 4 : #include <time.h> 5 : #include <assert.h> 6 : #ifdef __cplusplus 7 : #include <algorithm> 8 : #endif 9 : 10 : #ifndef TYPE 11 : #define TYPE int 12 : #endif 13 : 14 : 15 : #define swap(a,b) do { TYPE tmp = (a); (a) = (b); (b) = tmp; } while (0) 16 : 17 : 18 : 19 : // バブル・ソート 20 : void bubble_sort(TYPE* data, size_t size) { 21 : size_t i, j; 22 : for (i = 0; i < size-1; ++i) { 23 : for (j = size; --j > i;) { 24 : if (data[j] < data[j-1]) 25 : swap(data[j], data[j-1]); 26 : } 27 : } 28 : } 29 : 30 : 31 : // 選択ソート 32 : void selection_sort(TYPE* data, size_t size) { 33 : size_t i, j; 34 : for (i = 0; i < size; ++i) { 35 : size_t min = i; 36 : for (j = i+1; j < size; ++j) { 37 : if (data[j] < data[min]) 38 : min = j; 39 : } 40 : swap(data[i], data[min]) ; 41 : } 42 : } 43 : 44 : 45 : // 挿入ソート 46 : void insert_sort(TYPE* data, size_t size) { 47 : size_t i, j; 48 : for (i = 1; i < size; ++i) { 49 : TYPE tmp = data[i]; 50 : for (j = i; j > 0 && tmp < data[j-1]; --j) 51 : data[j] = data[j-1]; 52 : data[j] = tmp; 53 : } 54 : } 55 : 56 : 57 : // 挿入ソート (やなうらお版) 58 : void yane_insert_sort(TYPE* data, size_t size) { 59 : size_t i, j; 60 : for (i = 1; i < size; i++) { 61 : TYPE tmp = data[i]; 62 : if (data[i-1] > tmp) { 63 : j = i; 64 : do { 65 : data[j] = data[j-1]; 66 : --j; 67 : } while ( j > 0 && data[j-1] > tmp); 68 : data[j] = tmp; 69 : } 70 : } 71 : } 72 : 73 : 74 : // 挿入ソート(old) ※2007頃までのwikipediaに載っていたバージョン. 75 : void old_insert_sort(TYPE* data, size_t size) { 76 : size_t i, j, k; 77 : for (i = 0; ++i < size;) { 78 : for (j = i, k = i-1; j > 0 && data[j] < data[k]; --j, --k) 79 : swap(data[j], data[k]); 80 : } 81 : } 82 : 83 : 84 : // コム・ソート 85 : void comb_sort(TYPE* data, size_t size) { 86 : size_t h = size * 10 / 13; 87 : for (;;) { 88 : int swapFlag = 0; 89 : size_t i = 0; 90 : for (i = 0; i + h < size; ++i) { 91 : if (data[i + h] < data[i]) { 92 : swap(data[i + h], data[i]); 93 : swapFlag = 1; 94 : } 95 : } 96 : if (h <= 1) { 97 : if (!swapFlag) 98 : break; 99 : } else { 100 : h = h * 10 / 13; 101 : } 102 : } 103 : } 104 : 105 : 106 : // コム・ソート11 107 : void comb_sort11(TYPE* data, size_t size) { 108 : size_t h = size * 10 / 13; 109 : for (;;) { 110 : size_t i; 111 : int swapFlag = 0; 112 : for (i = 0; i + h < size; ++i) { 113 : if (data[i + h] < data[i]) { 114 : swap(data[i + h], data[i]); 115 : swapFlag = 1; 116 : } 117 : } 118 : if (h <= 1) { 119 : if (!swapFlag) 120 : break; 121 : } else if ((h == 9) | (h == 10)) { 122 : h = 11; 123 : } else { 124 : h = h * 10 / 13; 125 : } 126 : } 127 : } 128 : 129 : 130 : // 工夫なしのquickソート. 131 : void quick_sort(TYPE* data, size_t size) { 132 : TYPE m; 133 : TYPE *l, *r, *e; 134 : if (size <= 1) 135 : return; 136 : m = data[size / 2]; 137 : l = data; 138 : e = data + size; 139 : r = e - 1; 140 : for (;;) { 141 : while (*l < m) 142 : ++l; 143 : while (m < *r) 144 : --r; 145 : if (l >= r) 146 : break; 147 : swap(*l, *r); 148 : ++l; 149 : } 150 : quick_sort(data, l - data); 151 : quick_sort(l , e - l ); 152 : } 153 : 154 : 155 : 156 : // quickソート+挿入ソート (32個以下になったら挿入ソートに切替) 157 : void ex_quick_sort(TYPE* data, size_t size) { 158 : TYPE m; 159 : TYPE *l, *r, *e; 160 : if (size <= 32) { 161 : if (size <= 1) 162 : return; 163 : insert_sort(data, size); 164 : return; 165 : } 166 : m = data[size / 2]; 167 : l = data; 168 : e = data + size; 169 : r = e - 1; 170 : for (;;) { 171 : while (*l < m) 172 : ++l; 173 : while (m < *r) 174 : --r; 175 : if (l >= r) 176 : break; 177 : swap(*l, *r); 178 : ++l; 179 : } 180 : ex_quick_sort(data, l - data); 181 : ex_quick_sort(l , e - l ); 182 : } 183 : 184 : 185 : 186 : // quickソート+挿入ソート (32個以下になったら挿入ソートに切替) 187 : void y_quick_sort(TYPE* data, size_t size) { 188 : TYPE m; 189 : TYPE *l, *r, *e; 190 : if (size <= 32) { 191 : if (size <= 1) 192 : return; 193 : yane_insert_sort(data, size); 194 : return; 195 : } 196 : m = data[size / 2]; 197 : l = data; 198 : e = data + size; 199 : r = e - 1; 200 : for (;;) { 201 : while (*l < m) 202 : ++l; 203 : while (m < *r) 204 : --r; 205 : if (l >= r) 206 : break; 207 : swap(*l, *r); 208 : ++l; 209 : } 210 : y_quick_sort(data, l - data); 211 : y_quick_sort(l , e - l ); 212 : } 213 : 214 : 215 : 216 : // qsort用の比較関数. 217 : int qsort_cmp(const void* a0, const void* b0) { 218 : const TYPE* a = (const TYPE* )a0; 219 : const TYPE* b = (const TYPE* )b0; 220 : return *a - *b; 221 : } 222 : 223 : 224 : 225 : // Cライブラリの qsort を使った場合. 226 : void c_qsort(TYPE* data, size_t size) { 227 : qsort(data, size, sizeof(TYPE), qsort_cmp); 228 : } 229 : 230 : 231 : 232 : #ifdef __cplusplus 233 : // std::sort を使ったモノ. 234 : void std_sort(TYPE* data, size_t size) { 235 : std::sort(data, data+size); 236 : } 237 : #endif 238 : 239 : 240 : 241 : // =========================================================================== 242 : 243 : typedef void (*SortFunc)(TYPE*, size_t size); 244 : 245 : void benchmark(const char *name, SortFunc sortFunc, int seed, size_t size, size_t count) { 246 : unsigned i, j, ofs = 0; 247 : double elapsed, start_time; 248 : TYPE* data = (TYPE*) malloc(size * sizeof(TYPE) * count); 249 : srand(seed); 250 : for (i = 0; i < size * count; ++i) 251 : data[i] = rand(); 252 : start_time = clock(); 253 : for (j = 0; j < count; ++j) { 254 : sortFunc(&data[ofs], size); 255 : ofs += size; 256 : } 257 : elapsed = clock() - start_time; 258 : printf("%s:%13.3fμ秒 (%e秒)\n", name, elapsed / (CLOCKS_PER_SEC*count) * 1000000, elapsed / (CLOCKS_PER_SEC*count) ); 259 : free(data); 260 : } 261 : 262 : 263 : // 264 : int main(int argc, char **argv) { 265 : size_t size = (argc >= 2) ? atoi(argv[1]) : 100; 266 : size_t count = (argc >= 3) ? atoi(argv[2]) : 1; 267 : int all = (argc >= 4) ? atoi(argv[3]) : 0; // 遅いアルゴリズムも試す時. 268 : int seed = 1; //time(0); 269 : printf("個数 %d, 処理回数 %d\n", size, count); 270 : if (all) { // O(n^2) 271 : benchmark("buble sort ", &bubble_sort , seed, size, count); 272 : benchmark("selection sort ", &selection_sort , seed, size, count); 273 : benchmark("insert sort ", &insert_sort , seed, size, count); 274 : benchmark("insert sort(yane)", &yane_insert_sort, seed, size, count); 275 : } 276 : { // O(n log n) 277 : benchmark("comb sort ", &comb_sort , seed, size, count); 278 : benchmark("comb sort11 ", &comb_sort11 , seed, size, count); 279 : benchmark("quick sort ", &quick_sort , seed, size, count); 280 : benchmark("quick+insert sort", &ex_quick_sort , seed, size, count); 281 : benchmark("quick+yane-insert", &y_quick_sort , seed, size, count); 282 : #ifdef __cplusplus 283 : benchmark("std::sort ", &std_sort , seed, size, count); 284 : #endif 285 : benchmark("qsort ", &c_qsort , seed, size, count); 286 : } 287 : return 0; 288 : }