diff options
| author | Thomas Schmucker <ts@its1.de> | 2020-11-29 19:04:47 +0100 |
|---|---|---|
| committer | Thomas Schmucker <ts@its1.de> | 2020-11-29 19:04:47 +0100 |
| commit | 28d9e48724cd0f0748fea5e0a24e57c92caa2a4c (patch) | |
| tree | 7db44231e25f0b31e1409cb31c92e98e6c2bfc5a /heap.c | |
| parent | 728b55d00f035c729059bf2e3f381a718ac3e149 (diff) | |
| download | data-structures-bottom-up-heapsort.tar.gz data-structures-bottom-up-heapsort.tar.bz2 data-structures-bottom-up-heapsort.zip | |
bottom-up-heapsort hinzugefügt.bottom-up-heapsort
Diffstat (limited to 'heap.c')
| -rw-r--r-- | heap.c | 66 |
1 files changed, 64 insertions, 2 deletions
| @@ -162,7 +162,68 @@ my_heapsort(T a[], size_t n) | |||
| 162 | } | 162 | } |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | // TODO: https://www.geeksforgeeks.org/how-to-check-if-a-given-array-represents-a-binary-heap/ | 165 | void |
| 166 | heapsort_bu(T *data, int n) // zu sortierendes Feld und seine Länge | ||
| 167 | { | ||
| 168 | T val; | ||
| 169 | int parent, child; | ||
| 170 | int root = n >> 1; // erstes Blatt im Baum | ||
| 171 | |||
| 172 | for ( ;; ) { | ||
| 173 | if ( root ) { // Teil 1: Konstruktion des Heaps | ||
| 174 | parent = --root; | ||
| 175 | val = data[root]; // zu versickernder Wert | ||
| 176 | } | ||
| 177 | else if ( --n ) { // Teil 2: eigentliche Sortierung | ||
| 178 | val = data[n]; // zu versickernder Wert vom Heap-Ende | ||
| 179 | data[n] = data[0]; // Spitze des Heaps hinter den Heap in | ||
| 180 | parent = 0; // den sortierten Bereich verschieben | ||
| 181 | } | ||
| 182 | else // Heap ist leer; Sortierung beendet | ||
| 183 | break; | ||
| 184 | |||
| 185 | while ( (child = (parent + 1) << 1) < n ) // zweites (!) Kind; | ||
| 186 | { // Abbruch am Ende des Heaps | ||
| 187 | if ( data[child - 1] > data[child] ) // größeres Kind wählen | ||
| 188 | --child; | ||
| 189 | |||
| 190 | data[parent] = data[child]; // größeres Kind nach oben rücken | ||
| 191 | parent = child; // in der Ebene darunter weitersuchen | ||
| 192 | } | ||
| 193 | |||
| 194 | if ( child == n ) // ein einzelnes Kind am Heap-Ende | ||
| 195 | { // ist übersprungen worden | ||
| 196 | if ( data[--child] >= val ) { // größer als der zu versick- | ||
| 197 | data[parent] = data[child]; // ernde Wert, also noch nach oben | ||
| 198 | data[child] = val; // versickerten Wert eintragen | ||
| 199 | continue; | ||
| 200 | } | ||
| 201 | |||
| 202 | child = parent; // 1 Ebene nach oben zurück | ||
| 203 | } | ||
| 204 | else { | ||
| 205 | if ( data[parent] >= val ) { // das Blatt ist größer als der | ||
| 206 | data[parent] = val; // zu versickernde Wert, der damit | ||
| 207 | continue; // direkt eingetragen werden kann | ||
| 208 | } | ||
| 209 | |||
| 210 | child = (parent - 1) >> 1; // 2 Ebenen nach oben zurück | ||
| 211 | } | ||
| 212 | |||
| 213 | while ( child != root ) // maximal zum Ausgangspunkt zurück | ||
| 214 | { | ||
| 215 | parent = (child - 1) >> 1; // den Vergleichswert haben wir bereits | ||
| 216 | // nach oben verschoben | ||
| 217 | if ( data[parent] >= val ) // größer als der zu versickernde | ||
| 218 | break; // Wert, also Position gefunden | ||
| 219 | |||
| 220 | data[child] = data[parent]; // Rückverschiebung nötig | ||
| 221 | child = parent; // 1 Ebene nach oben zurück | ||
| 222 | } | ||
| 223 | |||
| 224 | data[child] = val; // versickerten Wert eintragen | ||
| 225 | } | ||
| 226 | } | ||
| 166 | 227 | ||
| 167 | // ------------------------------------------- | 228 | // ------------------------------------------- |
| 168 | 229 | ||
| @@ -232,7 +293,8 @@ test_heapsort(void) | |||
| 232 | 293 | ||
| 233 | puts("sortiere...."); | 294 | puts("sortiere...."); |
| 234 | clock_t start = clock(); | 295 | clock_t start = clock(); |
| 235 | my_heapsort(array, NELEM(array)); | 296 | //my_heapsort(array, NELEM(array)); |
| 297 | heapsort_bu(array, NELEM(array)); | ||
| 236 | clock_t end = clock(); | 298 | clock_t end = clock(); |
| 237 | 299 | ||
| 238 | puts("teste..."); | 300 | puts("teste..."); |
