250 likes | 382 Views
Prioriteettijonot ja kekolajittelu (heapsort). Käytetään kekoa kahden ongelman ratkaisemiseen: Prioriteettijono: keko ylläpitää keko-ominaisuutta lisäys –ja poisto-operaatioiden kanssa, kukin operaatio vie O(log n) ajan
E N D
Prioriteettijonot ja kekolajittelu (heapsort) Käytetään kekoa kahden ongelman ratkaisemiseen: • Prioriteettijono: keko ylläpitää keko-ominaisuutta lisäys –ja poisto-operaatioiden kanssa, kukin operaatio vie O(log n) ajan • Lajittelu: O(n log n) huonoimmassa tapauksessa, tarvitsee vain vähän ylimääräistä muistia
Keon toteutus • Juuri = 1 • i:n vasen lapsi = 2*i • i:n oikea lapsi = 2*i+1 • i:n vanhempi = i/2 x[1] x[2] X[3] x[4] x[5] X[6] • Täydellinen binääripuu jonka jokaisen solmun avain on suurempi tai yhtäsuuri kun lasten avain • Suurimman alkion etsiminen on nopeaa
Keko – siftup Uudet alkiot lisätään aina taulukon viimeiseenpaikkaan, minkä jälkeen puu päivitetään keoksiseuraavalla funktiolla: kekoylos(alkio a[], intk) { while(k > 1 && PIENEMPI(a[k / 2], a[k])) { VAIHDA(a[k], a[k / 2]); k = k / 2; } } a[1] a[2] a[3] a[4] a[5] a[6]
Keko – siftdown Poisto maksimikeon juurisolmusta suoritetaan siten, että viimeinen taulukon alkio vaihdetaan juurisolmuun ja päivitetään tietorakenne keoksi seuraavalla funktiolla: kekoalas(alkio a[], intk, intn) { intj; while(2 * k <= n) { j = 2 * k; if(j < n && PIENEMPI(a[j], a[j + 1])) j++; if(!PIENEMPI(a[k], a[j])) break; VAIHDA(a[k], a[j]); k = j; } } a[1] a[2] a[3] a[4] a[5] a[6]
Prioriteettijonot • esim. käyttöjärjestelmä voisi käyttää prioriteettijonoa esittämään joukkoa prosesseja, joista valitaan seuraavaksi suoritukseen otettava • Diskreetissä simuloinnissa jonosta otetaan seuraava tapahtuma suoritettavaksi sekä mahdollisesti lisätään uusia tapahtumia jonoon
Kekoon perustuva prioriteettijono static alkio *pq; /* taulukon osoite */ staticintn; /* alkioiden lukumäärä */ void PQalusta(intmaxn) { if((pq = (alkio *)malloc((maxn + 1) * sizeof(alkio))) == (alkio *)NULL) { perror("Taulukon muistinvaraus"); exit(1); } n = 0; } int PQtyhja(){ returnn == 0; } void PQlisaa(alkio v) { pq[++n] = v; kekoylos(pq, n); } alkio PQpoistamax() { VAIHDA(pq[1], pq[n]); kekoalas(pq, 1, n - 1); return pq[n--]; }
Kekolajittelu (heapsort) Yhdistää pikalajittelun ja limityslajittelun edut • O(n log n) huonoimmassa tapauksessa aivan kuten limityslajittelu • Ei tarvitse lisätilaa aivan kuten pikalajittelu Parannettu versio valintalajittelusta: • Taulukko muutetaan keoksi, jonka jälkeen isoin alkio poistetaan keosta ja laitetaan lajiteltuun järjestykseen Ei ole stabiili
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 1 3 5 7 2 4 8 11 1 3 5 7 2 4 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 1 3 5 11 2 4 8 7 1 3 5 11 2 4 8 7
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 1 3 8 11 2 4 5 7 1 3 8 11 2 4 5 7
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 1 11 8 7 2 4 5 3 1 11 8 7 2 4 5 3
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 11 7 8 3 2 4 5 1 11 7 8 3 2 4 5 1
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 1 7 8 3 2 4 5 1 7 8 3 2 4 5 11 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 8 7 5 3 2 4 1 8 7 5 3 2 4 1 11 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 1 7 5 3 2 4 1 7 5 3 2 4 8 11 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 7 3 5 1 2 4 7 3 5 1 2 4 8 11 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 4 3 5 1 2 4 3 5 1 2 7 8 11 7 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 5 3 4 1 2 5 3 4 1 2 7 8 11 7 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 2 3 4 1 2 3 4 1 5 7 8 11 5 7 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 4 3 2 1 4 3 2 1 5 7 8 11 5 7 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 1 3 2 1 3 2 4 5 7 8 11 4 5 7 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 3 1 2 3 1 2 4 5 7 8 11 4 5 7 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 2 1 2 1 3 4 5 7 8 11 3 4 5 7 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 2 1 2 1 3 4 5 7 8 11 3 4 5 7 8 11
Kekolajittelu (heapsort) #define pq(A) a[l - 1 + A] void kekolajittelu(alkio a[], intl, intr) { intk, n = r - l + 1; for(k = n / 2; k >= 1; k--) kekoalas(&pq(0), k, n); while(n > 1) { VAIHDA(pq(1), pq(n)); kekoalas(&pq(0), 1, --n); } } 1 2 3 4 5 7 8 11 1 2 3 4 5 7 8 11