3. Redezés algortmusok Redezés probléma Bemeet: Azoos típusú adatok H = {a,...,a } halmaza, amelyeke értelmezett egy leárs redezés relácó. (A redezés relácó maga s lehet bemeet paraméter.) Kmeet: A H halmaz elemeek egy redezéstartó felsorolása, tehát olya S = b,...,b sorozat, amelyre b b... b, és H = {b,...,b }. Belső redezés. H és S tárolása a főtárba törték. Külső redezés. Vagy H vagy S tárolása külső (lemezes állomáyba) tároló törték. Helybe redezés. Ha a meeet H halmazt és a kmeet S sorzatot ugyaaz az adatszerkezet tárolja. 3.. Kválasztó redezés Elv algortmus: S := ; Whle H <> /0 Do Beg x := H mmáls eleme; Tegyük x-et az S sorozat végére; Töröljük x-et H-ból; Ed m S H. ábra. A kválasztó redezés megvalósítása helybe Procedure Kvalasztored(Var T:Tomb); Var,j,m : Iteger; E : Elemtp; Beg For := To N- Do Beg {S=T[..-], H=T[..N]} m := ; For j := + To Tmeret Do If T[j].kulcs < T[m].kulcs The m := j; {T[m]=M(H)} E := T[]; T[] := T[m]; T[m] := E; {T[m] S végére; T[m] törlése H-ból} Ed Ed (* Kvalasztored *);
A KIVALASZTOREND futás dejéek elemzése Jelölje T () a végrehajtott elem művelet számát, ha H = = (5 + ) T () 5( ) + 5( ) + = ( ) = (5 + ( )) T () 5( ) + T () ( )(5 + ) = T l j () = T a () = T lr () = Θ( ) 3.. Beszúró redezés Elv algortmus: S := ; {üres output sorozat létesítés} Whle H <> /0 Do Beg x := H egy tetszőleges eleme; Szúrjuk be x-et az S sorozatba; Töröljük x-et H-ból; Ed j S H. ábra. A beszúró redezés megvalósítása helybe Procedure Beszurored (Var T:Tomb;K:RedRelTp); Var,j : Iteger; E : Elemtp; Beg For := To N Do Beg {S=T[..-], H=[..N]} E := T[]; j := -; Whle(j>0)Ad K(E,T[j]) Do Beg T[j+] := T[j]; Dec(j) Ed{whle}; {S[.. j] E < S[ j +.. ] } T[j+] := E; Ed{for} Ed (* BeszuroRed *);
A BESZUROREND futás dejéek elemzése Legjobb eset: az put redezett: T l j () = = 5 = 5( ) = O() Legroszabb eset: az put fordította redezett, ekkor a a Whle cklus magja -szer hajtódk végre, tehát T lr () = = ( ) = = = ( ) = O( ) Átlagos eset: rag(s,x) := { j : S[ j] > x} rag(s, T []) lehetséges értéke: 0,,, azoos valószíűséggel. Tehát a whle cklusmag végrehajtás számáak átlágos (várható) értéke: Tehát T a () = 3.3. Kupacredezés. (Wllams, Floyd 96) (0 + + ) = ( ) = ( ) = ( ) = = ( ) = O( ) = S = (M, R, Adat) adatszerkezet, ahol M =.., R = {Apa : M M} Apa() = dv, ha > Az S (fa) adatszerkezet Apa f u kapcsolattal s megadható: 3 5 6 7 8 9 0 3. ábra. Kupac adatszerkezet Bal() :=, ha Jobb() := +, ha + Def. S (maxmumos) kupac, ha redezett a -ra ézve. Általáosa, T = k..l. Ekkor több fából áll az adatszerkezet. Apa() = dv, ha k Def. Az a k,,a l sorozat (maxmumos) kupac, ha k..l ha r = dv k akkor a r a 3
{ Globáls programelemek a KupacRed eljáráshoz : Cost MaxN =??? ;{ a maxmáls tömbméret } Type Kulcstp =??? ;{ a redezés mező típusa } Adattp =??? ;{ az adatmező típusa } Elemtp = Record kulcs : Kulcstp; adat : Adattp Tomb = Array[..MaxN] Of Elemtp; } Procedure KupacRed(Var T : Tomb; N:Logt); Var : Logt; E : Elemtp; Procedure Sullyeszt(K,L : Logt ); {Iput : T[K+..L] kupac, Output: T[K..L] kupac } Var Apa,Fu : Logt; Beg{Sullyeszt} E:=T[K]; Apa:=K; Fu:=*Apa; Whle (Fu <= L) Do Beg If (Fu < L) Ad (T[Fu].kulcs < T[Fu+].kulcs) The Fu := Fu+; If E.kulcs >= T[Fu].kulcs The Break Else Beg T[Apa] := T[Fu]; Apa:=Fu; Fu:=*Apa Ed Ed{whle}; T[Apa] := E Ed{Sullyeszt}; Beg{KupacRed} For := N Dv Dowto Do Sullyeszt(, N);{Kupacépít} For := N Dowto Do Beg E:=T[]; T[]:=T[]; T[]:=E; Sullyeszt(,-) Ed{for }; Ed{KupacRed}; A kupacépítés futás deje Def. h-magaságú telített bárs fa: F h F 0 =, F h = (F h,f h ) ha h > 0 F h magassága = h F h potjaak száma h 0 k = h
Legye F -potú bárs kupac; F = Ekkor h(f) az a legksebb k, amelyre F k F k k lg( + ) h = lg( + ) A kupacépítés sorá a SULLYESZT ayszor hajtódk végre, mt aháy külöböző em levél részfája va a felépítedő -elemű kupacak.. ábra. Kupac részfá Jelölje R(, k) az -potú kupac k magasságú részfáak számát. R(,k) h k = h = h k k k Mvel SULLYESZT futás deje legrosszabb esetbe azo fa magasságával aráyos, amelybe a beszúrás törték, így a kupacépítés futás dejére a következőt kapjuk: T lr () h k=0 h R(, k)o(k) k= k O(k) O( k=0 k k ) = O( ) = O() = O() ( ) "Mdkét oldalt derválva": A KUPACREND futás deje x k = k=0 x ha x < kx k x = k=0 ( x) T lr () O() + O(h) k= O() +O( k= lg ) = O() +O( lg ) = O( lg ) 5
3.. A gyorsredezés (Hoare, 96) Elv algortmus: Legye FELOSZT(H,H b,x,h j ) olya művelet, amelyre teljesül a következő kmeett feltétel: x Pre(H) H b = {y : x y Pre(H) y x} H j = {y : y Pre(H) x < y} Tehát Pre(H) = H b {x} H j Ezért a következő oszd-meg-és-uralkodj elvű algortmus a redezés feladat helyes megoldását adja. Redez(H:Halmaz):Sorozat; Var x : Elemtp; S b, S j :Sorozat; H b, H j :Halmaz; Beg{Redez} If H The Beg S := H Retur(S) Feloszt(H,H b,x,h j ) ; {megosztás} S b := Redez(H b ); {uralkodás} S j := Redez(H j ); S := S b x S j ; {összerakás} Retur(S); Ed{Redez}; A Feloszt algortmus: Feloszt(H:Halmaz;Var H b,h j :Halmaz; x:elemtp); Beg{Feloszt} x felosztó elem választás; H b := /0; H j := /0; For y H Do {Ivarás: Max(H b ) x < M(H j )} If y x y x The H b := H b + {y} Else H j := H j + {y} {H = H b H j } Ed{Feloszt}; Megjegyzés: lehet H b = /0 vagy H j = /0 Megvalósítás: helybe, tömbbel Feloszt Lomuto-féle megvalósítása 6
bal jobb 8 7 3 5 6 j 8 7 3 5 6 j 8 7 3 5 6 j 8 7 j 3 5 6 7 8 3 5 6 3 8 7 5 6 j j 3 8 7 5 6 j 3 8 7 5 6 3 7 5 6 8 5. ábra. A FELOSZT eljárás működése. Fucto Feloszt( bal, jobb : Logt):Logt ; {H = T [bal.. jobb]} Var x,e : Elemtp;,j : Logt; Beg{Feloszt} x:= T[jobb]; :=bal-; For j:=bal To jobb- Do {Ivarás:H b = T [bal..],h j = T [ +.. j ]} If T [ j] x The Beg :=+; E:=T[]; T[]:=T[j]; T[j]:=E; :=+; E:=T[]; T[]:=T[jobb]; T[jobb]:=E; Feloszt:=; {H b = T [bal.. ],H j = T [ +.. jobb]} Ed{Feloszt}; Procedure GYORSREND(Var T:Tomb); Procedure Redez(bal,bobb : Logt); Var f : Logt; 7
Beg{Redez} f:= Feloszt(bal, jobb); If bal<f- The Redez(bal, f-); If f+<jobb The Redez(f+, jobb) Ed{Redez}; Beg Redez(, N) {GyorsRed} 3... A gyorsredezés hatékoysága Legrosszabb eset T lr () = max (T lr(q) + T lr ( q )) + Θ() 0 q T lr () max 0 q (cq + c( q ) ) + Θ() = c max 0 q (q + ( q ) ) + Θ() A q +( q ) kfejezés maxmumát a 0 q tervallum valamelyk végpotjába vesz fel, ezért max 0 q (q + ( q ) ) ( ) = +. Tehát T lr () c c( ) + Θ() c Tehát T lr () = O( ). Legjobb eset Ha mde FELOSZT felez az tervallumot (a felosztadó halmazt). Ekkor mde szte c a FELOSZT futás deje, és lg szt léve, a teljes futás dő: T l j () = O( lg) Átlagos eset 3.. lemma. Legye X a GYORSREND eljárás végrehajtása sorá a FELOSZT által végrehajtott összehasolítások száma elemű bemeetre. Ekkor GYORSREND teljes futás deje O( + X). Céluk X átlagos (várható) értékéek kszámítása. Legye a T bemeet tömb eleme redezette z,z,...,z, tehát z az -edk legksebb eleme a bemeetek. Defáljuk a Z j = {z,z +,...,z j } halmazokat, tehát a redezésbe z és z j között elemek halmaza. 8
Az algortmus mkor hasolítja össze z és z j elemeket? Vegyük észre, hogy bármely két elem legfeljebb egyszer hasolítódk össze,mert a felsztó elem em szerepel a felbotásba keletkező H b és H j halmazokba, amelyere rekurzív hívás törték. Jelölje eze összehasolítások számát X, j. X = Az összehasolítások E(X) átlagos számára kapjuk: = X j. j=+ E(X) = E( X j ) = j=+ = = = = E(X j ) j=+ Pr{z összehasolít z j } () j=+ z és z j összehasolítására akkor és csak akkor lkerül sor, ha az első felosztó elem a Z j halmazból vagy z, vagy z j. Mvel a Z j halmazak j + eleme va, és mde elem egyforma valószíűséggel lehet a felosztó elem, ezért Pr{z összehasolít z j } = Pr{z vagy z j első felosztó elem Z j -ből} = Pr{z első felosztó elem Z j -ből} = = + Pr{z j első felosztó elem Z j -ből} j + + j + j + () E(X) = = < = = = j=+ k= k= j + k + k = O(lg ) = = O( lg ) (3) Tehát GYORSREND átklagos futás deje T a () = O( lg) A gyorsredezés véletleített változata. 9
Fucto VeletleFeloszt( bal, jobb : Logt):Logt ; Var E : Elemtp; : Logt; Beg{VeletleFeloszt} :=Radom(jobb-bal+)+; E:=T[]; T[]:=T[jobb]; T[jobb]:=E; VeletleFeloszt:=Feloszt(bal,jobb); Ed{VeletleFeloszt}; A Hoare-féle felsosztás. { Globals objektumok a GyorsRed eljarashoz : Cost MaxN =??? ;(* a tömb dextpusa =..MaxN *) Type Kulcstp =??? ;(* a redezés mező típusa *) Adattp =??? ;(* az adatmező típusa *) Elemtp = Record kulcs : Kulcstp; adat : Adattp Tomb = Array[..N] Of Elemtp; Procedure BeszuroRed(Var T : Tomb); {\$I...} } Procedure GyorsRed(Var T : Tomb; N:Logt); Fucto HoareFeloszt( Bal,Jobb : Logt): Logt; Var Fe,E : Elemtp;,j : Logt; Beg Fe := T[(Bal+Jobb) Dv ]; := Bal-; j := Jobb+; Whle True Do Beg Repeat Ic() Utl (T[].kulcs >= Fe.kulcs); Repeat Dec(j) Utl (Fe.kulcs >= T[j.kulcs]); If < j The Beg E := T[]; T[] := T[j]; T[j] := E; Ed Else Beg Feloszt:=j; Ext 0
Ed{whle}; Ed (* HoareFeloszt *); Procedure Redez(bal,jobb : Logt); Var f : Logt; Beg f := HoareFeloszt(bal, jobb); If bal+0 < f The Redez(bal, f); If f+0 < jobb The Redez(f+, jobb) Ed (* Redez *); Beg(* GyorsRed *) Redez(, N); Beszurored(T) Ed (* GyorsRed *); 3.5. Általáos redezés algortmusok lr. esetéek alsó korlátja Dötés fa modell <= : <= > :3 :3 > <= > <,,3 > <= <,3,> :3 <,,3> :3 > <= > <3,,> <,3,> <3,,> 6. ábra. Dötés fa 3.. tétel. Mde elemet redező dötés fa magassága Ω( log ). Bzoyítás. A fa leveleek száma!, tehát ha a fa magassága h, akkor h! h lg(!) lg(( e ) ) = lg lg e = Ω( lg ) Mde általáos redezés algortmusra: T lr () = Ω( lg )
3.6. Leárs dejű redezés algortmusok Számláló redezés { Globáls programelemek a SzamlaloRed eljáráshoz : Cost N =??? ;(* a tomb dextpusa =..N *) M =??? ;(* a kulcstpus: 0..M *) Type Kulcstp = 0..M ;(* a redezes mezo kulcstpusa *) Adattp =??? ;(* az adatmezo tpusa *) Elemtp = Record kulcs : Kulcstp; adat : Adattp Tomb = Array[..N] Of Elemtp; } Procedure SzamlaloRed(Var T,T : Tomb); Var,j : Logt; S: Array[0..M] Of Logt; Beg For := 0 To M Do S[]:= 0; For := To N Do Ic(S[T[].kulcs]); For := To M Do S[]:= S[-]+S[]; (* S[]= {j T[j] <= } *) For := N DowTo Do Beg j := T[].kulcs; T[ S[j] ]:= T[]; Dec(S[j]); Ed Ed (* SzamlaloRed *); A SZAMLALOREND algortmus futás deje Θ(M + N) Stablak evezzük az olya redezés algortmust, amely megőrz az azoos kulcsú elemek sorredjét. Állítás. A SZAMLALOREND algortmus stabl redezés. Radx (számjegyes) redezés Példa: 39 70 70 39 57 36 39 36 657 57 36 57 839 657 839 657
36 39 57 70 70 839 657 839 Bemeet: H={a,...,a }, az elemek típusa Type KulcsTp=Array[..d] of Char {Strg}; Adattp =???; Elemtp=Record Adat:Adattp; Kulcs:Kulcstp A redezés relácó a lexkografkus redezés: X =< x,...,x d >,Y =< y,...,y d > Def. X < Z (lexkografkusa), ha ( )( d)((x < y ) ( j < )(x j = y j )) Elv: For :=d DowTo Do H Stabl redezése a kulcs -edk jegye szert; 0 3 5 6 7 8 9 70 36 57 657 39 839 7. ábra. Adatszerkezet a radx redezéshez. { Globals programelemek a RadxRe eljarashoz: Type Elemtp = Record (* a redezedo adatok tpusa *) kulcs : Strg[???]; adat :??? 3
Lac = ^Cella; Cella = Record Elem: Elemtp; Csat: Lac } Procedure RadxRed(Var L : Lac); Var T : Array[Char] Of Record Eleje,Vege:Lac; C : Char; E : Lac;, Maxhossz : Word; Beg Maxhossz := 0; E:=L;(* a maxmals szohossz meghatarozasa *) Whle E <> Nl Do Beg If Legth(E^.Elem.kulcs) > Maxhossz The Maxhossz := Legth(E^.Elem.kulcs); E:= E^.Csat For C := Chr(0) To Chr(55) Do (* ures reszlstak letrehozasa *) Beg New(T[C].Vege); T[C].Eleje:= T[C].Vege; For := Maxhossz Dowto Do Beg Whle L <> Nl Do (* szavak szetosztasa a reszlstakra, *) Beg (* az -edk betu szeret *) E:= L; L:= L^.Csat; If <= Legth(E^.Elem.kulcs) The C := E^.Elem.kulcs[] Else C := ; T[C].Vege^.Csat:= E; T[C].Vege:= E; L:= Nl; For C := Chr(55) DowTo Chr(0) Do Beg (* a reszlstak osszekapcsolasa *) T[C].Vege^.Csat:= L; L:= T[C].Eleje^.Csat; T[C].Vege:=T[C].Eleje; Ed
Ed Ed (* RadxRed *); Vödrös redezés Tegyük fel, hogy a redezedő H = {a,...,a } halmaz elemeek kulcsa a [0,) tervallumba eső valós számok (Real). Vegyük m db vödröt, V [0],...,V [m ] és osszuk szét a redezedő halmaz elemet a vödrökbe úgy, hogy az a elem a a.kulcs m sorszámú vödörbe kerüljö. Majd redezzük az egy vödörbe került elemeket, és a vödrök sorszáma szert övekvő sorrebe füzzük össze a redezett részsorozatokat. T V 3 5 6 7 8.78.7.39.6.7.9.. 0 3 5 6 7..7..3.6.39.68.7.78 9.3 8 0.68 9.9 8. ábra. Példa vödrös redezésre { Globáls programelemek a VodrosRed eljáráshoz : Cost N =??? ;(* a tömb dextpusa =..N *) Type Kulcstp = Real ;(* a redezés mező kulcstípusa *) Adattp =??? ;(* az adatmező típusa *) Elemtp = Record kulcs : Kulcstp; adat : Adattp Tomb = Array[..N] Of Elemtp; } Procedure VodrosRed(Var T,T : Tomb); Cost M=N; {a vödrök száma} Type Lac=^Cella; Cella=Record dex: Word; Csat: Lac 5
Var E: Elemtp; V:Array[0..M-] Of Lac;,j,k : Word; p,q,uj: Lac; Beg{VodrosRed} For := 0 To M- Do V[]:= Nl; For := To N Do Beg {az elemek szétosztása vödrökbe} j:= Truc(T[].kulcs*M); New(Uj); Uj^.dex:= ; Uj^.csat:= V[j]; V[j]:= Uj; := ; {a vödrökbe lévő elemek összefűzése és} For j := 0 To M- Do Beg{redezése beszúro redezéssel} p:= V[j]; Whle p <> Nl Do Beg E:= T[p^.dex]; k:= -; Whle (k>0) Ad (T[k].kulcs > E.kulcs) Do Beg T[k+]:= T[k]; Dec(k); T[k+]:= E; q:= p; p:= p^.csat; Dspose(q); Ic(); Ed{whle p}; Ed{for }; {VodrosRed} A VODROSREND futás dejéek elemzése. Legrosszabb eset Ez akkor következk be, ha mde elem egy vödörbe kerül, és mvel a vödröket beszúrú edezéssel redezzük, amem a legrosszabb esete O( ), így T lr () = O( ). Legjobb eset eset Ez akkor következk be, ha mde elem külö vödörbe kerül, így T l j () = O(). Átlagos eset eset T a () = Θ()> 6