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