diff options
| author | Thomas Schmucker <ts@its1.de> | 2020-07-22 17:30:45 +0200 |
|---|---|---|
| committer | Thomas Schmucker <ts@its1.de> | 2020-07-22 17:30:45 +0200 |
| commit | ac55496d881e0a17b3eff85f1faae5aafbc53b50 (patch) | |
| tree | 65b954e994d7bbfc76bc959876e28f7ea9fa708c /quicksort.c | |
| download | data-structures-ac55496d881e0a17b3eff85f1faae5aafbc53b50.tar.gz data-structures-ac55496d881e0a17b3eff85f1faae5aafbc53b50.tar.bz2 data-structures-ac55496d881e0a17b3eff85f1faae5aafbc53b50.zip | |
erster Commit
Diffstat (limited to 'quicksort.c')
| -rw-r--r-- | quicksort.c | 666 |
1 files changed, 666 insertions, 0 deletions
diff --git a/quicksort.c b/quicksort.c new file mode 100644 index 0000000..fa219e9 --- /dev/null +++ b/quicksort.c | |||
| @@ -0,0 +1,666 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <assert.h> | ||
| 4 | #include <time.h> | ||
| 5 | #include "util.h" | ||
| 6 | |||
| 7 | static int bigrand(void) | ||
| 8 | { | ||
| 9 | int x = (rand() << 24) | (rand() << 16) | (rand() << 8) | rand(); | ||
| 10 | if ( x < 0 ) | ||
| 11 | return -x; | ||
| 12 | return x; | ||
| 13 | } | ||
| 14 | |||
| 15 | static int randint(int l, int u) | ||
| 16 | { | ||
| 17 | return l + bigrand() % (u-l+1); | ||
| 18 | } | ||
| 19 | |||
| 20 | typedef int T; | ||
| 21 | |||
| 22 | static const int CUTOFF = 128; | ||
| 23 | |||
| 24 | static inline void | ||
| 25 | swap(T a[], int i, int j) | ||
| 26 | { | ||
| 27 | T t = a[i]; | ||
| 28 | a[i] = a[j]; | ||
| 29 | a[j] = t; | ||
| 30 | } | ||
| 31 | |||
| 32 | static void | ||
| 33 | insertsort(T a[], int n) | ||
| 34 | { | ||
| 35 | int i, j; | ||
| 36 | for ( i = 1; i < n; ++i ) | ||
| 37 | { | ||
| 38 | T t = a[i]; | ||
| 39 | for ( j = i; j > 0 && a[j-1] > t; --j ) | ||
| 40 | a[j] = a[j-1]; | ||
| 41 | a[j] = t; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | static void | ||
| 46 | quicksort(T a[], int n) | ||
| 47 | { | ||
| 48 | int i, last; | ||
| 49 | |||
| 50 | if ( n <= CUTOFF ) | ||
| 51 | return; | ||
| 52 | |||
| 53 | swap(a, 0, bigrand() % n); | ||
| 54 | |||
| 55 | last = 0; | ||
| 56 | for ( i = 1; i < n; ++i ) | ||
| 57 | if ( a[i] < a[0] ) | ||
| 58 | swap(a, ++last, i); | ||
| 59 | |||
| 60 | swap(a, 0, last); | ||
| 61 | |||
| 62 | quicksort(a, last); | ||
| 63 | quicksort(a+last+1, n-last-1); | ||
| 64 | } | ||
| 65 | |||
| 66 | void | ||
| 67 | my_quicksort(T a[], int n) | ||
| 68 | { | ||
| 69 | quicksort(a, n); | ||
| 70 | insertsort(a, n); | ||
| 71 | } | ||
| 72 | |||
| 73 | |||
| 74 | static int | ||
| 75 | cmp(const void *a, const void *b) | ||
| 76 | { | ||
| 77 | const int *pa = (const T *) a; | ||
| 78 | const int *pb = (const T *) b; | ||
| 79 | |||
| 80 | if ( *pa < *pb ) return -1; | ||
| 81 | if ( *pa > *pb ) return 1; | ||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | |||
| 85 | void | ||
| 86 | c_quicksort(T a[], int n) | ||
| 87 | { | ||
| 88 | qsort(a, n, sizeof(T), cmp); | ||
| 89 | } | ||
| 90 | |||
| 91 | /* This function takes last element as pivot, places | ||
| 92 | the pivot element at its correct position in sorted | ||
| 93 | array, and places all smaller (smaller than pivot) | ||
| 94 | to left of pivot and all greater elements to right | ||
| 95 | of pivot */ | ||
| 96 | int partition (int arr[], int low, int high) | ||
| 97 | { | ||
| 98 | int pivot = arr[high]; // pivot | ||
| 99 | int i = (low - 1); // Index of smaller element | ||
| 100 | |||
| 101 | for (int j = low; j <= high- 1; j++) | ||
| 102 | { | ||
| 103 | // If current element is smaller than or | ||
| 104 | // equal to pivot | ||
| 105 | if (arr[j] <= pivot) | ||
| 106 | { | ||
| 107 | i++; // increment index of smaller element | ||
| 108 | swap(arr, i, j); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | swap(arr, i + 1, high); | ||
| 112 | return (i + 1); | ||
| 113 | } | ||
| 114 | |||
| 115 | /* The main function that implements QuickSort | ||
| 116 | arr[] --> Array to be sorted, | ||
| 117 | low --> Starting index, | ||
| 118 | high --> Ending index */ | ||
| 119 | void quickSort(int arr[], int low, int high) | ||
| 120 | { | ||
| 121 | while (low < high) | ||
| 122 | { | ||
| 123 | /* pi is partitioning index, arr[p] is now | ||
| 124 | at right place */ | ||
| 125 | int pi = partition(arr, low, high); | ||
| 126 | |||
| 127 | if (pi - low < high - pi) | ||
| 128 | { | ||
| 129 | quickSort(arr, low, pi - 1); | ||
| 130 | low = pi + 1; | ||
| 131 | } | ||
| 132 | else | ||
| 133 | { | ||
| 134 | quickSort(arr, pi + 1, high); | ||
| 135 | high = pi - 1; | ||
| 136 | } | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | void g4g_quicksort(T a[], int n) | ||
| 141 | { | ||
| 142 | quickSort(a, 0, n-1); | ||
| 143 | } | ||
| 144 | |||
| 145 | |||
| 146 | static void three_way_quicksort(int a[], int l, int r) | ||
| 147 | { | ||
| 148 | int k; | ||
| 149 | T v = a[r]; | ||
| 150 | |||
| 151 | if ( r <= l ) | ||
| 152 | return; | ||
| 153 | |||
| 154 | int i = l-1, j = r, p = l-1, q = r; | ||
| 155 | |||
| 156 | for ( ;; ) { | ||
| 157 | while ( a[++i] < v ) | ||
| 158 | ; | ||
| 159 | while ( v < a[--j] ) | ||
| 160 | if ( j == l ) | ||
| 161 | break; | ||
| 162 | if ( i >= j ) | ||
| 163 | break; | ||
| 164 | |||
| 165 | swap(a, i, j); | ||
| 166 | |||
| 167 | if ( a[i] == v ) | ||
| 168 | swap(a, ++p, i); | ||
| 169 | if ( v == a[j] ) | ||
| 170 | swap(a, --q, j); | ||
| 171 | } | ||
| 172 | swap(a, i, r); j = i-1; i = i+1; | ||
| 173 | |||
| 174 | for ( k = l ; k <= p; ++k, --j ) | ||
| 175 | swap(a, k, j); | ||
| 176 | for ( k = r-1; k >= q; --k, ++i ) | ||
| 177 | swap(a, k, i); | ||
| 178 | |||
| 179 | three_way_quicksort(a, l, j); | ||
| 180 | three_way_quicksort(a, i, r); | ||
| 181 | } | ||
| 182 | |||
| 183 | void sed_quicksort(int a[], int n) | ||
| 184 | { | ||
| 185 | three_way_quicksort(a, 0, n-1); | ||
| 186 | } | ||
| 187 | |||
| 188 | /* ====================== HEAPSORT ======================= */ | ||
| 189 | |||
| 190 | #define LEFT(idx) (idx*2+1) | ||
| 191 | #define RIGHT(idx) (idx*2+2) | ||
| 192 | #define PARENT(idx) ((idx-1)/2) | ||
| 193 | |||
| 194 | static void | ||
| 195 | fixdown(T heap[], int i, int n) | ||
| 196 | { | ||
| 197 | for ( ;; ) { | ||
| 198 | const int l = LEFT(i); | ||
| 199 | const int r = RIGHT(i); | ||
| 200 | int m = i; | ||
| 201 | |||
| 202 | if ( l < n && heap[m] < heap[l] ) | ||
| 203 | m = l; | ||
| 204 | |||
| 205 | if ( r < n && heap[m] < heap[r] ) | ||
| 206 | m = r; | ||
| 207 | |||
| 208 | if ( m == i ) | ||
| 209 | break; | ||
| 210 | |||
| 211 | swap(heap, m, i); | ||
| 212 | |||
| 213 | i = m; | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | static void | ||
| 218 | heapify(T heap[], int n) | ||
| 219 | { | ||
| 220 | for ( int i = n / 2 - 1; i >= 0; --i ) | ||
| 221 | fixdown(heap, i, n); | ||
| 222 | } | ||
| 223 | |||
| 224 | void | ||
| 225 | my_heapsort(T a[], int n) | ||
| 226 | { | ||
| 227 | heapify(a, n); | ||
| 228 | |||
| 229 | for ( int i = n-1; i >= 0; --i ) { | ||
| 230 | swap(a, 0, i); | ||
| 231 | fixdown(a, 0, i); | ||
| 232 | } | ||
| 233 | } | ||
| 234 | |||
| 235 | void | ||
| 236 | heapsort_bu( T * data, int n ) // zu sortierendes Feld und seine Länge | ||
| 237 | { | ||
| 238 | T val; | ||
| 239 | int parent, child; | ||
| 240 | int root= n >> 1; // erstes Blatt im Baum | ||
| 241 | int count= 0; // Zähler für Anzahl der Vergleiche | ||
| 242 | |||
| 243 | for ( ; ; ) | ||
| 244 | { | ||
| 245 | if ( root ) { // Teil 1: Konstruktion des Heaps | ||
| 246 | parent= --root; | ||
| 247 | val= data[root]; // zu versickernder Wert | ||
| 248 | } | ||
| 249 | else | ||
| 250 | if ( --n ) { // Teil 2: eigentliche Sortierung | ||
| 251 | val= data[n]; // zu versickernder Wert vom Heap-Ende | ||
| 252 | data[n]= data[0]; // Spitze des Heaps hinter den Heap in | ||
| 253 | parent= 0; // den sortierten Bereich verschieben | ||
| 254 | } | ||
| 255 | else // Heap ist leer; Sortierung beendet | ||
| 256 | break; | ||
| 257 | |||
| 258 | while ( (child= (parent + 1) << 1) < n ) // zweites (!) Kind; | ||
| 259 | { // Abbruch am Ende des Heaps | ||
| 260 | if ( ++count, data[child-1] > data[child] ) // größeres Kind wählen | ||
| 261 | --child; | ||
| 262 | |||
| 263 | data[parent]= data[child]; // größeres Kind nach oben rücken | ||
| 264 | parent= child; // in der Ebene darunter weitersuchen | ||
| 265 | } | ||
| 266 | |||
| 267 | if ( child == n ) // ein einzelnes Kind am Heap-Ende | ||
| 268 | { // ist übersprungen worden | ||
| 269 | if ( ++count, data[--child] >= val ) { // größer als der zu versick- | ||
| 270 | data[parent]= data[child]; // ernde Wert, also noch nach oben | ||
| 271 | data[child]= val; // versickerten Wert eintragen | ||
| 272 | continue; | ||
| 273 | } | ||
| 274 | |||
| 275 | child= parent; // 1 Ebene nach oben zurück | ||
| 276 | } | ||
| 277 | else | ||
| 278 | { | ||
| 279 | if ( ++count, data[parent] >= val ) { // das Blatt ist größer als der | ||
| 280 | data[parent]= val; // zu versickernde Wert, der damit | ||
| 281 | continue; // direkt eingetragen werden kann | ||
| 282 | } | ||
| 283 | |||
| 284 | child= (parent - 1) >> 1; // 2 Ebenen nach oben zurück | ||
| 285 | } | ||
| 286 | |||
| 287 | while ( child != root ) // maximal zum Ausgangspunkt zurück | ||
| 288 | { | ||
| 289 | parent= (child - 1) >> 1; // den Vergleichswert haben wir bereits | ||
| 290 | // nach oben verschoben | ||
| 291 | if ( ++count, data[parent] >= val ) // größer als der zu versickernde | ||
| 292 | break; // Wert, also Position gefunden | ||
| 293 | |||
| 294 | data[child]= data[parent]; // Rückverschiebung nötig | ||
| 295 | child= parent; // 1 Ebene nach oben zurück | ||
| 296 | } | ||
| 297 | |||
| 298 | data[child]= val; // versickerten Wert eintragen | ||
| 299 | } | ||
| 300 | } | ||
| 301 | |||
| 302 | /*----------------------------------------------------------------------*/ | ||
| 303 | /* BOTTOM-UP HEAPSORT */ | ||
| 304 | /* Written by J. Teuhola <teuhola@cs.utu.fi>; the original idea is */ | ||
| 305 | /* probably due to R.W. Floyd. Thereafter it has been used by many */ | ||
| 306 | /* authors, among others S. Carlsson and I. Wegener. Building the heap */ | ||
| 307 | /* bottom-up is also due to R. W. Floyd: Treesort 3 (Algorithm 245), */ | ||
| 308 | /* Communications of the ACM 7, p. 701, 1964. */ | ||
| 309 | /*----------------------------------------------------------------------*/ | ||
| 310 | |||
| 311 | #define element float | ||
| 312 | |||
| 313 | /*-----------------------------------------------------------------------*/ | ||
| 314 | /* The sift-up procedure sinks a hole from v[i] to leaf and then sifts */ | ||
| 315 | /* the original v[i] element from the leaf level up. This is the main */ | ||
| 316 | /* idea of bottom-up heapsort. */ | ||
| 317 | /*-----------------------------------------------------------------------*/ | ||
| 318 | static void siftup(T v[], int i, int n) | ||
| 319 | { | ||
| 320 | int j, start; | ||
| 321 | T x; | ||
| 322 | |||
| 323 | start = i; | ||
| 324 | x = v[i]; | ||
| 325 | j = i<<1; | ||
| 326 | while (j<=n) | ||
| 327 | { | ||
| 328 | if (j<n) | ||
| 329 | if (v[j]<v[j+1]) | ||
| 330 | j++; | ||
| 331 | v[i] = v[j]; | ||
| 332 | i = j; j = i<<1; | ||
| 333 | } | ||
| 334 | j = i>>1; | ||
| 335 | while (j>=start) | ||
| 336 | { if (v[j]<x) | ||
| 337 | { v[i] = v[j]; | ||
| 338 | i = j; j = i>>1; | ||
| 339 | } | ||
| 340 | else break; | ||
| 341 | } | ||
| 342 | v[i] = x; | ||
| 343 | } /* End of siftup */ | ||
| 344 | |||
| 345 | /*----------------------------------------------------------------------*/ | ||
| 346 | /* The heapsort procedure; the original array is r[0..n-1], but here */ | ||
| 347 | /* it is shifted to vector v[1..n], for convenience. */ | ||
| 348 | /*----------------------------------------------------------------------*/ | ||
| 349 | void bottom_up_heapsort(T r[], int n) | ||
| 350 | { | ||
| 351 | int k; | ||
| 352 | T x; | ||
| 353 | T *v; | ||
| 354 | |||
| 355 | v = r-1; /* The address shift */ | ||
| 356 | |||
| 357 | /* Build the heap bottom-up, using siftup. */ | ||
| 358 | for (k=n>>1; k>1; k--) siftup(v, k, n); | ||
| 359 | |||
| 360 | /* The main loop of sorting follows. The root is swapped with the last */ | ||
| 361 | /* leaf after each sift-up. */ | ||
| 362 | for (k=n; k>1; k--) | ||
| 363 | { | ||
| 364 | siftup(v, 1, k); | ||
| 365 | x = v[k]; v[k] = v[1]; v[1] = x; | ||
| 366 | } | ||
| 367 | } /* End of bottom_up_heapsort */ | ||
| 368 | |||
| 369 | |||
| 370 | |||
| 371 | /* ====================== HEAPSORT ======================= */ | ||
| 372 | |||
| 373 | /* ====================== INTROSORT ======================= */ | ||
| 374 | |||
| 375 | |||
| 376 | |||
| 377 | static void | ||
| 378 | introsort(T a[], int n, int h) | ||
| 379 | { | ||
| 380 | int i, last; | ||
| 381 | |||
| 382 | if ( n <= CUTOFF ) | ||
| 383 | return; | ||
| 384 | |||
| 385 | if ( --h == 1 ) { | ||
| 386 | my_heapsort(a, n); | ||
| 387 | return; | ||
| 388 | } | ||
| 389 | |||
| 390 | swap(a, 0, bigrand() % n); | ||
| 391 | |||
| 392 | last = 0; | ||
| 393 | for ( i = 1; i < n; ++i ) | ||
| 394 | if ( a[i] < a[0] ) | ||
| 395 | swap(a, ++last, i); | ||
| 396 | |||
| 397 | swap(a, 0, last); | ||
| 398 | |||
| 399 | introsort(a, last, h); | ||
| 400 | introsort(a+last+1, n-last-1, h); | ||
| 401 | } | ||
| 402 | |||
| 403 | void | ||
| 404 | my_introsort(T a[], int n) | ||
| 405 | { | ||
| 406 | int h = 1; | ||
| 407 | |||
| 408 | for ( int nn = 1; nn < n; nn <<= 1 ) | ||
| 409 | ++h; | ||
| 410 | |||
| 411 | introsort(a, n, h); | ||
| 412 | insertsort(a, n); | ||
| 413 | } | ||
| 414 | |||
| 415 | static void pp_quicksort_impl(T a[], int l, int u) | ||
| 416 | { | ||
| 417 | if ( u - l < CUTOFF ) | ||
| 418 | return; | ||
| 419 | |||
| 420 | swap(a, l, randint(l, u)); | ||
| 421 | |||
| 422 | T t = a[l]; | ||
| 423 | int i = l; | ||
| 424 | int j = u+1; | ||
| 425 | for (;;) { | ||
| 426 | do i++; while ( /*i <= u &&*/ a[i] < t ); | ||
| 427 | do j--; while ( a[j] > t ); | ||
| 428 | if ( i > j ) | ||
| 429 | break; | ||
| 430 | swap(a, i, j); | ||
| 431 | } | ||
| 432 | swap(a, l, j); | ||
| 433 | pp_quicksort_impl(a, l, j-1); | ||
| 434 | pp_quicksort_impl(a, j+1, u); | ||
| 435 | } | ||
| 436 | |||
| 437 | void | ||
| 438 | pp_quicksort(T a[], int n) | ||
| 439 | { | ||
| 440 | pp_quicksort_impl(a, 0, n-1); | ||
| 441 | insertsort(a, n); | ||
| 442 | } | ||
| 443 | |||
| 444 | static void pp_quicksort_impl_it(T a[], int l, int u, int h) | ||
| 445 | { | ||
| 446 | if ( --h == 1 ) { | ||
| 447 | my_heapsort(a+l, u-l+1); | ||
| 448 | return; | ||
| 449 | } | ||
| 450 | |||
| 451 | while ( u-l >= CUTOFF ) | ||
| 452 | { | ||
| 453 | swap(a, l, randint(l, u)); | ||
| 454 | |||
| 455 | T t = a[l]; | ||
| 456 | int i = l; | ||
| 457 | int j = u+1; | ||
| 458 | |||
| 459 | for (;;) { | ||
| 460 | do i++; while ( /*i <= u && */ a[i] < t ); | ||
| 461 | do j--; while ( a[j] > t ); | ||
| 462 | if ( i > j ) | ||
| 463 | break; | ||
| 464 | swap(a, i, j); | ||
| 465 | } | ||
| 466 | swap(a, l, j); | ||
| 467 | |||
| 468 | if ( j - l < u - j ) | ||
| 469 | { | ||
| 470 | pp_quicksort_impl_it(a, l, j-1, h); | ||
| 471 | l = j + 1; | ||
| 472 | } | ||
| 473 | else | ||
| 474 | { | ||
| 475 | pp_quicksort_impl_it(a, j+1, u, h); | ||
| 476 | u = j - 1; | ||
| 477 | } | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 481 | void | ||
| 482 | pp_quicksort_it(T a[], int n) | ||
| 483 | { | ||
| 484 | int h = 1; | ||
| 485 | |||
| 486 | for ( int nn = 1; nn < n; nn <<= 1 ) | ||
| 487 | ++h; | ||
| 488 | |||
| 489 | pp_quicksort_impl_it(a, 0, n-1, h); | ||
| 490 | insertsort(a, n); | ||
| 491 | } | ||
| 492 | |||
| 493 | int | ||
| 494 | binary_search(T x, T v[], int n) | ||
| 495 | { | ||
| 496 | int low, high; | ||
| 497 | |||
| 498 | low = 0; | ||
| 499 | high = n-1; | ||
| 500 | while ( low <= high ) { | ||
| 501 | int mid = low + ((high - low) / 2); | ||
| 502 | if ( x > v[mid] ) | ||
| 503 | low = mid + 1; | ||
| 504 | else if ( x < v[mid] ) | ||
| 505 | high = mid - 1; | ||
| 506 | else | ||
| 507 | return mid; | ||
| 508 | } | ||
| 509 | return -1; | ||
| 510 | } | ||
| 511 | |||
| 512 | int | ||
| 513 | lower_bound(T x, T v[], int n) | ||
| 514 | { | ||
| 515 | int low, high; | ||
| 516 | |||
| 517 | low = 0; | ||
| 518 | high = n; | ||
| 519 | while ( low < high ) { | ||
| 520 | int mid = low + ((high - low) / 2); | ||
| 521 | |||
| 522 | if ( x > v[mid] ) | ||
| 523 | low = mid + 1; | ||
| 524 | else | ||
| 525 | high = mid; | ||
| 526 | } | ||
| 527 | return x == v[low] ? low : -1; | ||
| 528 | } | ||
| 529 | |||
| 530 | int | ||
| 531 | upper_bound(T x, T v[], int n) | ||
| 532 | { | ||
| 533 | int low, high; | ||
| 534 | |||
| 535 | low = 0; | ||
| 536 | high = n; | ||
| 537 | while ( low < high ) { | ||
| 538 | int mid = low + ((high - low) / 2); | ||
| 539 | |||
| 540 | if ( x >= v[mid] ) | ||
| 541 | low = mid + 1; | ||
| 542 | else | ||
| 543 | high = mid; | ||
| 544 | } | ||
| 545 | return ( low > 0 && x == v[low-1] ) ? low-1 : -1; | ||
| 546 | } | ||
| 547 | |||
| 548 | /* TESTTREIBER */ | ||
| 549 | |||
| 550 | |||
| 551 | void gen_testset_random(T a[], int n) | ||
| 552 | { | ||
| 553 | for ( int i = 0; i < n; ++i ) | ||
| 554 | a[i] = bigrand(); | ||
| 555 | } | ||
| 556 | |||
| 557 | void gen_testset_random2(T a[], int n) | ||
| 558 | { | ||
| 559 | for ( int i = 0; i < n; ++i ) | ||
| 560 | a[i] = bigrand() % 100; | ||
| 561 | } | ||
| 562 | |||
| 563 | void gen_testset_asc(T a[], int n) | ||
| 564 | { | ||
| 565 | for ( int i = 0; i < n; ++i ) | ||
| 566 | a[i] = i; | ||
| 567 | } | ||
| 568 | |||
| 569 | void gen_testset_desc(T a[], int n) | ||
| 570 | { | ||
| 571 | for ( int i = n; i >= 0; --i ) | ||
| 572 | a[i] = i; | ||
| 573 | } | ||
| 574 | |||
| 575 | void gen_testset_unique(T a[], int n) | ||
| 576 | { | ||
| 577 | for ( int i = 0; i < n; ++i ) | ||
| 578 | a[i] = 1; | ||
| 579 | } | ||
| 580 | |||
| 581 | void test_sorting(T a[], int n) | ||
| 582 | { | ||
| 583 | for ( int i = 1; i < n; ++i ) | ||
| 584 | if ( a[i-1] > a[i] ) { | ||
| 585 | puts("Fehler!"); | ||
| 586 | exit(EXIT_SUCCESS); | ||
| 587 | } | ||
| 588 | } | ||
| 589 | |||
| 590 | void do_one_test(int n, void (*do_sort)(T a[], int n), void (*gen_testset)(T a[], int n)) | ||
| 591 | { | ||
| 592 | T *a; | ||
| 593 | clock_t start, ende; | ||
| 594 | |||
| 595 | a = malloc(sizeof(T) * n); | ||
| 596 | |||
| 597 | (*gen_testset)(a, n); | ||
| 598 | |||
| 599 | start = clock(); | ||
| 600 | (*do_sort)(a, n); | ||
| 601 | ende = clock(); | ||
| 602 | |||
| 603 | test_sorting(a, n); | ||
| 604 | |||
| 605 | free(a); | ||
| 606 | |||
| 607 | printf("%10.3lf sec", ((double) ende - start) / CLOCKS_PER_SEC); | ||
| 608 | fflush(stdout); | ||
| 609 | } | ||
| 610 | |||
| 611 | void do_all_tests(const char *msg, int n, void (*do_sort)(T a[], int n)) | ||
| 612 | { | ||
| 613 | printf("%-15.15s n=%-10d: ", msg, n); | ||
| 614 | do_one_test(n, do_sort, gen_testset_random); | ||
| 615 | do_one_test(n, do_sort, gen_testset_random2); | ||
| 616 | do_one_test(n, do_sort, gen_testset_asc); | ||
| 617 | do_one_test(n, do_sort, gen_testset_desc); | ||
| 618 | do_one_test(n, do_sort, gen_testset_unique); | ||
| 619 | putchar('\n'); | ||
| 620 | } | ||
| 621 | |||
| 622 | /* ENDE TESTTREIBER */ | ||
| 623 | |||
| 624 | int main(void) | ||
| 625 | { | ||
| 626 | const int n = 20000000; | ||
| 627 | |||
| 628 | srand(time(0)); | ||
| 629 | do_all_tests("my_heapsort", n, my_heapsort); | ||
| 630 | do_all_tests("heapsort_bu", n, heapsort_bu); | ||
| 631 | do_all_tests("bottom_up_heapsort", n, bottom_up_heapsort); | ||
| 632 | do_all_tests("c_quicksort", n, c_quicksort); | ||
| 633 | //do_all_tests("g4g_quicksort", n, g4g_quicksort); | ||
| 634 | //do_all_tests("sed_quicksort", n, sed_quicksort); | ||
| 635 | do_all_tests("my_introsort", n, my_introsort); | ||
| 636 | //do_all_tests("my_quicksort", n, my_quicksort); | ||
| 637 | do_all_tests("pp_quicksort", n, pp_quicksort); | ||
| 638 | do_all_tests("pp_quicksort_it", n, pp_quicksort_it); | ||
| 639 | |||
| 640 | return 0; | ||
| 641 | } | ||
| 642 | |||
| 643 | #if 0 | ||
| 644 | int _main(void) | ||
| 645 | { | ||
| 646 | T array[20]; | ||
| 647 | |||
| 648 | for ( int i = 0; i != NELEM(array); ++i ) | ||
| 649 | array[i] = rand() % 10; | ||
| 650 | |||
| 651 | sort(array, NELEM(array)); | ||
| 652 | print(array, NELEM(array)); | ||
| 653 | |||
| 654 | int value; | ||
| 655 | while ( scanf("%d", &value) == 1 && value != -1 ) { | ||
| 656 | int bs = binary_search(value, array, NELEM(array)); | ||
| 657 | int lb = lower_bound(value, array, NELEM(array)); | ||
| 658 | int ub = upper_bound(value, array, NELEM(array)); | ||
| 659 | |||
| 660 | printf("bs: %d - lb: %d - ub: %d\n", bs, lb, ub); | ||
| 661 | } | ||
| 662 | |||
| 663 | return EXIT_SUCCESS; | ||
| 664 | } | ||
| 665 | #endif | ||
| 666 | |||
