1 / 13

Hajoita ja hallitse (divide and conquer)

Hajoita ja hallitse (divide and conquer). Pikalajittele n-alkioinen taulukko Divide : Jaetaan taulukko kahdeksi alitaulukoksi tukialkion (pivot) x suhteen: Conqueror : Lajitellaan alitaulukot rekursiivisesti Yhdistäminen: triviaali.  x.  x. x. Animaatio.

kyros
Download Presentation

Hajoita ja hallitse (divide and conquer)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Hajoita ja hallitse (divide and conquer) • Pikalajittele n-alkioinen taulukko • Divide: Jaetaan taulukko kahdeksi alitaulukoksi tukialkion (pivot) x suhteen: • Conqueror: Lajitellaan alitaulukot rekursiivisesti • Yhdistäminen: triviaali x x x

  2. Animaatio • http://www.cs.brockport.edu/cs/java/apps/sorters/quicksort.html

  3. Osiointi 55 41 59 26 53 58 97 93 41 26 53 55 59 58 97 93  55  55

  4. x x x l m r x x x l m r Yksinkertaisin versio x x x ? voidpikalajittelu1(alkio a[], intl, intr){ inti, m, x=a[l]; if (l >= r) return; m = l; for (i = l+1; i <= r; i++) if (a[i] < x) vaihda(a, ++m, i); vaihda(a, l, m); pikalajittelu1(a, l, m-1); pikalajittelu1(a, m+1, r);} l m i r ensimmäinen alkio on tukialkio enintään yksi alkio => palaa

  5. Kaikki alkiot samoja 55 55 55 55 55 55 55 55 l,m r Taulukon jako on hyvin epätasainen: toiseen alitaulukkoon kuuluu kaikki muut alkiot paitsi tukialkio.

  6. Kaksisuuntainen osiointi x x x ? voidpikalajittelu3(alkio a[], intl, intr){ inti, j; alkiox; if (l >= r) return; x = a[l];i = l;j = r+1; for (;;) { doi++; while (i <= r && a[i] < x); doj--; while (a[j] > x); if (i > j)break; vaihda(a, i, j);} vaihda(a, l, j); pikalajittelu3(a, l, j-1); pikalajittelu3(a,j+1, r);} l i r j enintään yksi alkio => palaa Pysähdytään yhtäsuuriin elementteihin

  7. Alkiot nousevassa järjestyksessä 55 56 57 58 58 59 60 61 l,m r Taulukon jako on hyvin epätasainen: toiseen alitaulukkoon kuuluu kaikki muut alkiot paitsi tukialkio.

  8. Satunnaistaminen+ pienten alitaulukoiden lisäyslajittelu intcutoff = 50; voidpikalajittelu4(alkio a[], intl, intr){ inti, j; alkiot, temp; if (r - l < cutoff) return; vaihda(a, l, randint(l, r)); x = a[l];i = l;j = r+1; for (;;) { doi++; while (i <= r && a[i] < x); doj--; while (a[j] > x); if (i > j) break; vaihda(a, l, j); } vaihda(a, l, j); pikalajittelu4(a, l, j-1); pikalajittelu4(a, j+1, r); } pieni taulukko => palaa vaihdetaan satunnainen alkio tukialkioksi Ohjelman päättyessä taulukko a:n sisältö ei ole lajiteltuna, vaan se on ryhmitelty pieniin satunnaisesti järjestettyihin arvoihin. Kukin ryhmä sisältää pienempiä arvoja kuin sen oikealla puolella olevat. Lajittelu: pikalajittelu4(a, l, r); lisayslajittelu3(a, l, r);

  9. Kolmivaiheinen osiointi • Tehokas runsaasti samoja avaimia sisältävässä tapauksessa

  10. Algoritmin kompleksisuus • Huonoin tapaus: toiselle puolelle jää N-1 alkiota ja toiselle 0 => O(N2) • Paras tapaus: molemmille puolille jää yhtä monta alkiota=> O(N log N) • Myös keskimääräinen kompleksisuus on O(N log N)

  11. Tukialkion valinta • Valitaan vakiopaikasta, esim. taulukon ensimmäinen. Toimii hyvin satunnaiselle syötteelle. Melkein järjestetylle syötteelle jako on erittäin epätasainen. • Valitaan tukialkioksi ensimmäisen, keskimmäisen ja viimeisen alkion mediaani. • Valitaan tukialkio satunnaisesti. Erittäin todennäköisesti osittelu on tasainen.

  12. Valitaan k:ksi pienin alkio rekursiivisesti void valitse_rekursiivisesti(alkio a[], intl, intr, intk) { inti; if(r <= l) return; i = osioi(a, l, r); if(i > k) valitse_rekursiivisesti(a, l, i - 1, k); if(i < k) { valitse_rekursiivisesti(a, i + 1, r, k); } • k:s alkio löytyy taulukosta kohdasta a[k-1] vaikkei taulukkoa ole kokonaan lajiteltukaan

  13. Valitaan k:ksi pienin alkio iteratiivisesti void valitse_iteratiivisesti(alkio a[], intl, intr, intk) { inti; while(r > l) { i = osioi(a, l, r); if(i >= k) r = i - 1; if(i <= k) l = i + 1; } } • k:s alkio löytyy taulukosta kohdasta a[k-1] vaikkei taulukkoa ole kokonaan lajiteltukaan

More Related