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