320 likes | 506 Views
Kuplalajittelu (bubble sort). Verrataan vierekkäisiä taulukon alkioita ja vaihdetaan niiden paikkaa tarvittaessa Jokaisella iteraatiolla pienin alkio lajittelemattomien joukosta ”kuplii” oikealle paikalleen lajiteltujen joukkoon. Kuplalajittelu (bubble sort). Kuplalajittelu C-kielellä.
E N D
Kuplalajittelu (bubble sort) • Verrataan vierekkäisiä taulukon alkioita ja vaihdetaan niiden paikkaa tarvittaessa • Jokaisella iteraatiolla pienin alkio lajittelemattomien joukosta ”kuplii” oikealle paikalleen lajiteltujen joukkoon
Kuplalajittelu C-kielellä lajitellaan a[l]..a[r] void kuplalajittelu(alkio a[], int l, int r){ int i, j; for(i = l; i <= r; i++) for(j = r; j > i; j--)VERTVAIHDA(a[j - 1], a[j]); } Käydään kaikki alkiot läpi
Kuplalajittelun analyysi • Huonoimmassa tapauksessa suoritetaan n(n-1)/2 vertailua ja vaihtoan-1 i n-1 i=1 j=11= i=1i=n(n-1)/2
Kuorilajittelu (shellsort) • h-lajittelu sekvenssille lisäyksiä, päättyen arvoon 1 • Esim. 3280-lajittelu, sitten 1093-lajittelu, sitten 364-lajittelu, sitten 121-lajittelu, sitten 40-lajittelu, sitten 13-lajittelu, sitten 4-lajittelu ja lopuksi 1-lajittelu • Menetelmän tehokkuus perustuu alkioiden siirtämiseen pitkiä matkoja
Ensin 13-lajittelu, sitten 4-lajittelu A S O R T I N G E X A M P L E AE O R T I N G E X A M P L S A E O R T I N G E X A M P L S A E O R T I N G E X A M P L S A E N R T I O G E X A M P L S A E N G T I O R E X A M P L S A E N G E I O R T X A M P L S A E N G E I O R T X A M P L S A E A G E I N R T X O M P L S A E A G E I N M T X O R P L S A E A G E I N M P X O R T L S A E A G E I N M P L O R T X S A E A G E I N M P L O R T X S
1-lajitellaan,4-lajiteltu tiedosto A I A G E L E M P S N R T X O A I A G E L E M P S N R T X O A A I G E L E M P S N R T X O A A I G E L E M P S N R T X O A A E G I L E M P S N R T X O A A E G I L E M P S N R T X O A A E E G I L M P S N R T X O A A E E G I L M P S N R T X O A A E E G I L M P S N R T X O A A E E G I L M P S N R T X O A A E E G I L M N P S R T X O A A E E G I L M N P R S T X O A A E E G I L M N P R S T X O A A E E G I L M N P R S T X O A A E E G I L M N O P R S T X
Kuorilajittelu (shellsort) void kuorilajittelu(alkio a[], int l, int r) { int i, h; for(h = 1; h <= (r - l) / 9; h = 3 * h + 1) ; for(; h > 0; h /= 3) for(i = l + h; i <= r; i++) { int j = i; alkio v = a[i]; while(j >= l + h &&PIENEMPI(v, a[j-h])) { a[j] = a[j - h]; j -= h; } a[j] = v; } } lajitellaan a[l]..a[r] h-lajittelu taikasekvenssille h:n arvoja lisäyslajittelu, kun h=1
Kuorilajittelun h:n arvot Mitä sekvenssiä käytetään? • 1,4,13,40,121,… ei hullumpi, helppo laskea • 1,3,7,21,48,112,… suunnilleen paras tunnettu Avoimia kysymyksiä: • Onko olemassa parempia sekvenssejä? • Keskimääräinen ajoaika O(N1+C) ? O(N lg N) ?
Jakaumalajittelu(distribution counting) • Oletetaan tietueen avaimen olevan kokonaisluku [0,k] • Lasketaan kullekin avaimelle sitä pienempien avaimien lukumäärä. Tämän tiedon avulla avain saadaan oikeaan paikkaan. • Esim. jos on 17 x:ää pienempiä avaimia. x kuuluu paikkaan 18.
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 a lkm 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 0 a 0 0 0 0 lkm lukumäärien alustaminen 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 0 a 0 0 0 1 lkm lukumäärien laskenta 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 0 0 1 lkm lukumäärien laskenta 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 0 1 1 lkm lukumäärien laskenta 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 0 1 2 lkm lukumäärien laskenta 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 0 2 2 lkm lukumäärien laskenta 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 0 2 2 lkm 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 0 2 2 lkm kumulatiivinen summa 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 1 2 2 lkm kumulatiivinen summa 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 1 3 2 lkm kumulatiivinen summa 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 1 3 5 lkm kumulatiivinen summa 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 1 3 5 lkm 0 1 2 3 4 b Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 0 1 4 5 lkm alkioiden lajittelu 0 1 2 3 4 b 4 Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 1 1 4 5 lkm alkioiden lajittelu 0 1 2 3 4 b 1 4 Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 1 2 4 5 lkm alkioiden lajittelu 0 1 2 3 4 b 1 3 4 Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 1 2 5 5 lkm alkioiden lajittelu 0 1 2 3 4 b 1 3 4 4 Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 1 3 5 5 lkm alkioiden lajittelu 0 1 2 3 4 b 1 3 3 4 4 Syöte: a[l]…a[r] Tulos: b[l]…b[r] Aputaulukko: lkm[0]…lkm[m], missä m isoin avain
Jakaumalajittelu(distribution counting 0 1 2 3 4 2 3 4 5 1 4 1 3 4 3 1 a 1 3 3 5 lkm 0 1 2 3 4 1 b 3 3 4 4
Jakaumalajittelu lajiteltava taulukko nolla avainta on 0:aa pienempiä, kuusi on 1:tä pienempiä, kymmenen on 2:ta pienempiä, 12 on kolmosta pienempiä (keskimmäinen taulukko) kuusi 0:aa neljä 1:tä kaksi 2:ta neljä 3:ta
Jakaumalajittelu lajitellaan a[l]..a[r] void jakaumalajittelu(alkio a[], int l, int r) { int i, j, lkm[m]; int b[ARVO_MAX]; for(j = 0; j < m; j++) lkm[j] = 0; for(i = l; i <= r; i++) lkm[a[i] + 1]++; for(j = 1; j < m; j++) lkm[j] += lkm[j - 1]; for(i = l; i <= r; i++) b[lkm[a[i]]++] = a[i]; for(i = l; i <= r; i++) a[i] = b[i]; } esiintymien lukumäärät lukumäärien alustaminen lukumäärien laskenta kumulatiivinen summa alkioiden lajittelu lajitellun kopiointi
Jakaumalajittelun analyysi (m) for(j = 0; j < m; j++) lkm[j] = 0; for(i = l; i <= r; i++) lkm[a[i] + 1]++; for(j = 1; j < m; j++) lkm[j] += lkm[j - 1]; for(i = l; i <= r; i++) b[lkm[a[i]]++] = a[i]; for(i = l; i <= r; i++) a[i] = b[i]; (n) (m) (n) (r) (m+n), n=r-l