Documente Academic
Documente Profesional
Documente Cultură
Metode de SORTARE
focus
Mihai Scorþaru
Operaþia de ordonare a unor articole în funcþie de diverse criterii este foarte
des întâlnitã în practicã. Se cunosc o mulþime de algoritmi de sortare,
majoritatea fiind foarte simpli. În cadrul acestui articol vom încerca sã
realizãm o prezentare comparativã a performanþelor care pot fi obþinute
folosind douã dintre cele mai cunoscute metode de sortare.
zul cel mai defavorabil. atribuire efectuate asupra indecºilor sau a altor elemente
având structurã similarã.
Mãsurarea performanþelor De fapt, practic, atribuirile pot fi evitate în totalitate
Vom studia performanþele algoritmilor din punct de vede- dacã operaþiile nu se efectueazã asupra elementelor vecto-
re teoretic. Pentru aceasta va trebui sã alegem o mãsurã a rului propriu-zis, ci asupra unui vector auxiliar de indecºi.
performanþelor acestora. Deºi, în practicã, acestã metodã este folositã aproape întot-
Nu vom putea compara doi algoritmi doar pe baza or- deauna, vom lucra direct cu elementele ºirului pentru a ob-
dinului de complexitate deoarece, în multe cazuri, cei doi þine o mai bunã caracterizare a performanþelor algoritmi-
algoritmi vor avea acelaºi ordin de complexitate. lor studiaþi.
Nu putem mãsura nici timpii de execuþie ai unor pro- Din aceste motive, trebuie reþinut faptul cã o mãsurã a
grame, deoarece vom prezenta doar teoretic algoritmii, fã- performanþelor general acceptatã este reprezentatã de nu-
rã a studia efectiv ºi implementãrile. mãrul comparãrilor efectuate.
Pentru a determina mãsura performanþelor vom iden- Totuºi, în cele ce urmeazã, vom folosi douã mãsuri di-
24 tifica operaþiile care sunt efectuate în timpul execuþiei. ferite ale performanþei pentru a caracteriza algoritmii ºi
anume: numãrul comparãrilor efectuate ºi numãrul atribu- care trebuie amplasat în poziþia curentã, vom realiza o in-
irilor efectuate. terschimbare.
Apare în mod evident întrebarea: cum vom determina
numãrul comparãrilor ºi numãrul atribuirilor? Rãspunsul Varianta #1
este unul foarte simplu: le vom numãra. Versiunea în pseudocod a algoritmului care realizeazã exact
Pentru a numãra comparãrile ºi atribuirile vom folosi aceste operaþii este urmãtoarea:
douã variabile care vor fi incrementate de fiecare datã când
se executã o comparare de articole sau o atribuire de arti- atr ← 0
cole. În acest articol vom denumi aceste variabile comp ºi comp ← 0
focus
atr. pentru i ← 1, n executã
În cazul în care o comparare apare în cadrul condiþiei min ← ai % atribuire %
de continuare a unei structuri repetitive anterior condiþio- atr ← atr + 1
nate, atunci se va executa o comparare pentru fiecare exe- ind ← i
cuþie a corpului buclei ºi una suplimentarã în momentul în pentru j ← i + 1, n executã
care condiþia de executare a corpului buclei nu mai este sa- dacã min > aj atunci % comparare %
tisfãcutã. min ← aj % atribuire %
În cazul în care compararea apare în cadrul condiþiei atr ← atr + 1
de continuare a unei structuri repetitive posterior condi- ind ← j
þionate, nu se executã ºi compararea suplimentarã, fiind sfârºit dacã
executate doar comparãrile corespunzãtoare execuþiilor comp ← comp + 1
corpului buclei. aind ← ai % atribuire %
În cazul în care compararea apare în cadrul condiþiei atr ← atr + 1
decizionale a unei structuri alternative, numãrul compara- ai ← min % atribuire %
þiilor va creºte indiferent de rezultatul evaluãrii condiþiei. atr ← atr + 1
Vom determina numãrul de atribuiri ºi comparaþii sfârºit pentru
pentru ºiruri formate din 10, 20, 30, ..., 100 de numere. sfârºit pentru
În continuare vom prezenta metodele directe de sorta- Pentru realizarea interschimbãrii nu a fost nevoie de o
re ºi vom realiza o prezentare comparativã a performanþe- variabilã auxiliarã, variabila min având acest rol.
lor acestora. Se observã cã, pentru un ºir cu n elemente, numãrul de
Pentru simplificare, vom considera cã vom sorta un ºir comparãri este acelaºi, indiferent de valoarea celor n nu-
de n numere întregi ºi cã acestea trebuie ordonate crescã- mere.
tor. Aceastã alegere nu reduce generalitatea, deoarece vom Numãrul atribuirilor poate varia doar datoritã atribu-
lua în considerare doar comparaþiile ºi atribuirile efectuate irii din interiorul structurii alternative dacã.
asupra elementelor vectorului ºi asupra variabilelor auxi- Cazul cel mai favorabil apare atunci când aceastã atri-
liare. Vom ignora toate celelalte atribuiri ºi comparãri, buire se executã de cele mai puþine ori. Se observã cã, în
chiar dacã ele sunt efectuate tot asupra unor numere în- cazul în care ºirul iniþial este deja sortat, aceastã atribuire
tregi. nu este executatã deloc, deci cel mai favorabil caz este cel
în care ºirul dat este deja sortat.
Sortarea prin selecþie Cazul cel mai defavorabil apare atunci când atribuirea
Ideea care stã la baza sortãrii prin selecþie este aceea de a se executã de cele mai multe ori. Am putea crede cã numã-
alege primul element al ºirului sortat ºi a-l aºeza pe prima rul maxim este (n - 1) + (n - 2) + ... + 2 + 1 = n · (n - 1) / 2.
Ginfo nr. 1 - ianuarie 2001
poziþie. Presupunem cã acest element s-a aflat pe poziþia x Totuºi, datoritã permutãrilor efectuate în cadrul algorit-
în ºirul iniþial; primul element în ºirul iniþial va fi mutat în mului, nu putem gãsi nici un ºir pentru care aceastã atribu-
poziþia x. În continuare vom aplica aceeaºi regulã pentru ire sã fie executatã de n · (n - 1) / 2 ori.
restul ºirului (începând cu al doilea element) ºi vom obþine La prima execuþie a buclei pentru exterioare, bucla
primele douã elemente ale ºirului sortat. Vom aplica apoi pentru interioarã se executã de n - 1 ori, deci numãrul
regula pentru al treilea element, al patrulea element etc. maxim de execuþii ale atribuirii este n - 1. Însã, dupã efec-
pânã când vom obþine ºirul sortat. tuarea permutãrii, pe ultima poziþie ajunge cel mai mare
element al ºirului, deci la urmãtoarea execuþie a buclei
Prezentarea algoritmului pentru exterioare, numãrul maxim de execuþii ale atribu-
Se observã cã vom parcurge ºirul iniþial pentru a amplasa irii este n - 3. Este evident cã, la fiecare pas, numãrul de
pe poziþia curentã elementul corespunzãtor din ºirul or- execuþii se reduce cu 2.
donat. Pentru a realiza amplasarea va trebui sã cãutãm cel Este uºor de gãsit un ºir care sã ducã la o astfel de exe-
mai mic element al subºirului rãmas, deci vom realiza o cuþie a algoritmului: ºirul trebuie sã fie ordonat descrescã-
parcurgere a acestui subºir. Dupã identificarea elementului tor.
25
Se observã cã nu existã nici o altã configuraþie a ºirului În tabelul 2 este prezentatã o statisticã a numãrului de
care sã determine un numãr mai mare de execuþii ale atribuiri ºi comparãri efectuate în diferite situaþii. Pentru a
atribuirii, deci putem considera cã ºirul ordonat descrescã- nu crea confuzii vom pãstra toate cele ºapte coloane ale
tor reprezintã cazul cel mai defavorabil pentru acest algo- tabelului anterior, chiar dacã informaþiile sunt redundante.
ritm.
În tabelul 1 este prezentatã o statisticã a numãrului de N Favorabil Mediu Defavorabil
atribuiri ºi comparãri efectuate în diferite situaþii.
comp atr comp atr comp atr
10 45 30 45 30 45 30
N Favorabil Mediu Defavorabil 20 190 60 190 60 190 60
30 435 90 435 90 435 90
focus
atr ← 0
comp ← 0
pentru i ← 1, n executã
ind ← i
pentru j ← i + 1, n executã
dacã aind > aj atunci % comparare %
ind ← j
sfârºit dacã F i g u ra 1 : S e l e c t S o rt : c a zu l me d i u - a t ri b u i ri
comp ← comp + 1
aux ← aind % atribuire % Graficul numãrului de atribuiri pentru cazul cel mai
atr ← atr + 1 defavorabil este prezentat în figura 2.
aind ← ai % atribuire %
atr ← atr + 1
ai ← aux % atribuire %
Ginfo nr. 1 - ianuarie 2001
atr ← atr + 1
sfârºit pentru
sfârºit pentru
focus
Figura 3: SelectSort: comparãri atr ← atr + 1
pentru k ← j, i - 1 executã
Din grafice putem trage concluzia cã algoritmul Se- aux1 ← ak+1 % atribuire %
lectSort are un ordin de complexitate pãtratic indiferent de atr ← atr + 1
structura datelor de intrare. ak+1 ← aux2 % atribuire %
atr ← atr + 1
Sortarea prin inserare aux2 ← aux1 % atribuire %
Algoritmul de sortare prin inserare constã în parcurgerea atr ← atr + 1
ºirului neordonat ºi inserarea elementului curent i în pozi- sfârºit pentru
þia corectã în subºirul de i - 1 elemente deja ordonat. aj ← aux2 % atribuire %
Mai exact, se începe cu elementul de pe poziþia a doua atr ← atr + 1
ºi se verificã dacã este sau nu mai mic decât primul ele- sfârºit pentru
ment. În caz afirmativ cele douã elemente sunt interschim-
bate. Dupã eventuala interschimbare suntem siguri cã sub- Trebuie remarcat faptul cã pentru a deplasa elementele
ºirul format din primele douã elemente este ordonat. Se avem nevoie, la fiecare pas, de trei atribuiri.
trece la al treilea element ºi se determinã poziþia în care Vom încerca sã gãsim acum cazul cel mai favorabil din
trebuie inserat acesta în subºirul format din primele douã punct de vedere al comparãrilor efectuate. În cel mai favo-
elemente. Elementul este amplasat în poziþia corectã, iar rabil caz corpul buclei cât timp nu ar trebui sã se execute
elementele care urmeazã dupã el sunt deplasate la dreapta nici o datã. Pentru aceasta va trebui ca elementul curent sã
cu o poziþie. Dupã inserare, subºirul format din primele fie inserat întotdeauna pe prima poziþie, deci ºirul ar trebui
trei elemente este sortat. Se continuã pânã la inserarea tu- sã fie ordonat descrescãtor.
turor elementelor. În final vom obþine un ºir ordonat. Cazul cel mai defavorabil apare atunci când corpul bu-
Existã douã variante importante ale algoritmului, fie- clei cât timp se executã de cele mai multe ori, aºadar ele-
care având diferite subvariante. Diferenþa principalã cons- mentul curent ar trebui sã nu îºi modifice niciodatã pozi-
tã în modul în care este realizatã cãutarea: cãutare liniarã þia, deci ºirul trebuie sã fie ordonat crescãtor.
sau binarã. Vom studia acum cazul cel mai favorabil ºi cel mai
Vom prezenta câte douã subvariante pentru fiecare defavorabil pentru atriburi. În cel mai favorabil caz, cor-
dintre modalitãþile de cãutare. Datoritã faptului cã algorit- pul buclei interioare pentru nu trebuie sã se execute nici
mul de cãutare liniarã este mai simplu, vom trata, pentru o datã. Aceasta înseamnã cã nu sunt necesare deplasãri,
început, subvariantele în care poziþia elementului curent deci elementele nu trebuie sã îºi modifice poziþia. Ca ur-
este determinatã folosind o cãutare liniarã. mare, în cel mai favorabil caz ºirul trebuie sã fie ordonat
crescãtor.
Varianta #1 subvarianta #1 Cazul cel mai defavorabil apare în situaþia în care cor-
Ginfo nr. 1 - ianuarie 2001
Vom prezenta acum o variantã în care se foloseºte un al- pul buclei interioare pentru se executã de cele mai multe
goritm de cãutare liniarã pentru a determina poziþia în care ori. Aceasta înseamnã cã elementul curent ar trebui inserat
este inserat elementul curent aflat iniþial pe o poziþie i. Pen- întotdeauna pe prima poziþie, deci ºirul trebuie sã fie or-
tru aceasta vom parcurge ºirul de la stânga la dreapta pânã donat descrescãtor.
vom gãsi un element mai mare decât cel curent, iar apoi Se observã cã situaþia este oarecum bizarã. Cazul cel
vom deplasa celelalte elemente (pânã la poziþia i - 1) cu o mai favorabil pentru comparãri este cazul cel mai defavo-
poziþie la dreapta ºi vom insera elementul curent în subºi- rabil pentru atribuiri, iar cazul cel mai defavorabil pentru
rul ordonat pe poziþia corectã. Dacã nu existã nici un ele- comparãri este cazul cel mai favorabil pentru atribuiri.
ment mai mare decât cel de pe poziþia i, atunci poziþia aces- Datoritã faptului cã nu poate fi determinatã o echiva-
tuia nu va mai fi modificatã. lenþã absolutã între un anumit numãr de atribuiri ºi un
Pseudocodul algoritmului descris este urmãtorul: anumit numãr de comparãri, nu existã posibilitatea deter-
minãrii cu exactitate a celui mai favorabil sau celui mai de-
atr ← 0 favorabil caz. În tabelul 3 este prezentatã o statisticã a
comp ← 0 numãrului de atribuiri ºi comparãri efectuate în diferite
27
situaþii. Datoritã situaþiei prezentate, nu mai existã coloa- Vom încerca sã gãsim acum cazul cel mai favorabil
nele corespunzãtoare cazului celui mai favorabil ºi cazului pentru acest algoritm. Se observã cã la fiecare execuþie a
celui mai puþin favorabil. Ele sunt înlocuite de coloane buclei cât timp se efectueazã câte o atribuire ºi câte o com-
corespunzãtoare unui ºir ale cãrui elemente sunt ordonate parare, iar în exteriorul acesteia nu existã alte bucle care sã
crescãtor ºi unui ºir ale cãrui elemente sunt ordonate des- influenþeze numãrul total de comparãri ºi atribuiri. Putem
crescãtor. trage concluzia cã vom avea aceeaºi configuraþie pentru
ºirul care trebuie ordonat atât în cazul cel mai favorabil
N Crescãtor Mediu Descrescãtor din punct de vedere al comparãrilor, cât ºi în cazul cel mai
favorabil din punct de vedere al atribuirilor. Situaþia este
comp atr comp atr comp atr
focus
10 54 18 31 86 9 153
aceeaºi ºi pentru cazul cel mai defavorabil.
20 209 38 113 326 19 608 Cazul cel mai favorabil apare atunci când corpul buclei
30 464 58 244 716 29 1363
40 819 78 425 1259 39 2418 cât timp nu se executã nici o datã, deci poziþia elementu-
50 1274 98 655 1953 49 3773
60 1829 118 935 2799 59 5428 lui curent nu se modificã. Aºadar, ºirul trebuie sã fie ordo-
70 2484 138 1263 3798 69 7383 nat crescãtor. Cazul cel mai defavorabil apare atunci când
80 3239 158 1642 4947 79 9638
90 4094 178 2071 6244 89 12193 corpul buclei cât timp se executã de cele mai multe ori,
100 5049 198 2547 7702 90 15048
deci elementul curent va fi inserat întotdeauna pe prima
Ta b e l u l 3 : In se rtS o rt v a ri a n ta # 1 su b v a ri a n ta # 1 poziþie. Aºadar, ºirul trebuie sã fie ordonat descrescãtor.
În tabelul 4 este prezentatã o statisticã a numãrului de
Varianta #1 subvarianta #2 atribuiri ºi comparãri efectuate în diferite situaþii.
Se observã imediat o posibilitate de optimizare a algorit-
mului anterior. Putem pãstra elementul a cãrui poziþie tre- N Favorabil Mediu Defavorabil
buie modificatã într-o variabilã auxiliarã ºi apoi vom putea
comp atr comp atr comp atr
deplasa elementele la dreapta cu o poziþie, parcurgând 10 9 18 30 39 54 63
subºirul deja ordonat de la dreapta la stânga. Astfel, pentru 20 19 38 113 132 209 228
30 29 58 243 272 464 493
deplasãri nu se vor mai efectua trei atribuiri la fiecare pas, 40 39 78 425 464 819 858
50 49 98 654 703 1274 1323
ci doar una singurã, deoarece interschimbarea este înlocu- 60 59 118 934 993 1829 1888
itã de o singurã atribuire. 70 69 138 1264 1333 2484 2553
80 79 158 1642 1721 3239 3318
De asemenea, putem determina poziþia în care trebuie 90 89 178 2070 2159 4094 4183
100 99 198 2550 2649 5049 5148
inserat elementul parcurgând subºirul ordonat de la dreap-
ta la stânga. Aºadar, vom parcurge elementele pânã vom T a b e l u l 4 : I n se rt S o rt v a ri a n t a # 1 su b v a ri a n t a # 2
gãsi unul care este mai mic decât elementul curent sau
ajungem pe prima poziþie. Compararea subvariantelor
Pe mãsurã ce efectuãm cãutarea, putem sã efectuãm ºi Se observã cã, pentru cele douã subvariante, numãrul com-
deplasãrile. parãrilor este aproximativ acelaºi deci, din acest punct de
În final, vom insera elementul curent în poziþia deter- vedere ele sunt la fel de performante. Singurele diferenþe
minatã. apar în cazul mediu, dar sunt nesemnificative ºi sunt dato-
Pseudocodul acestui algoritm este prezentat în conti- rate faptului cã ºirurile folosite pentru determinarea nu-
nuare: mãrului de atribuiri ºi comparãri în cazul mediu au fost
generate aleator.
atr ← 0 În cazul mediu ºi în cazul cel mai defavorabil numãrul
comp ← 0 atribuirilor efectuate de cea de-a doua subvariantã a algo-
pentru i ← 2, n executã ritmului este de aproximativ trei ori mai mic decât numã-
Ginfo nr. 1 - ianuarie 2001
focus
F i g u ra 5 : I n s e rt S o rt # 1 : c a zu l c e l m a i atr ← atr + 1
defavorabil - atribuiri sfârºit pentru
aj ← aux2 % atribuire %
Se observã cã graficele numãrului de atribuiri au forma atr ← atr + 1
unor funcþii pãtratice. sfârºit pentru
În figura 6 vom prezenta graficul numãrului de com-
parãri pentru cazul mediu ºi cazul cel mai defavorabil. Se observã cã singura diferenþã faþã de prima subva-
riantã a primei variante este datã de modul în care se reali-
zeazã cãutarea. Aceasta se realizeazã în timp constant
O(log i) unde i este indicele elementului a cãrui poziþie se
cautã ºi nu depinde de configuraþia ºirului.
Existã o micã variaþie nesemnificativã datoritã faptului
cã în urma înjumãtãþirilor, diferenþa dintre numãrul ele-
mentelor din cele douã jumãtãþi ar putea fi 1, deci, în unele
Figura 6: InsertSort #1: comparãri cazuri, s-ar putea ca numãrul de paºi necesari pentru gãsi-
rea poziþiilor sã varieze. În urma studierii rezultatelor se
Din grafice putem trage concluzia cã algoritmul In- va observa cã, din nou, cazul cel mai favorabil din punct de
sertSort are un ordin de complexitate pãtratic pentru cazul vedere al comparãrilor este identic cu cazul cel mai defa-
mediu ºi cazul cel mai defavorabil. În cel mai favorabil caz, vorabil din punct de vedere al atribuirilor ºi cazul cel mai
cea de-a doua subvariantã a algoritmului ruleazã în timp defavorabil din punct de vedere al comparãrilor este iden-
liniar. tic cu cazul cel mai favorabil din punct de vedere al atribu-
irilor. Totuºi, diferenþele sunt foarte mici ºi pot fi ignorate.
Varianta #2 subvarianta #1 Deplasãrile se realizeazã în acelaºi mod, deci vom avea
Urmãtoarea variantã pe care o prezentãm foloseºte un al- cazul cel mai defavorabil atunci când elementele sunt inse-
goritm de cãutare binarã pentru a determina poziþia în care rate pe prima poziþie (ºirul este ordonat descrescãtor) ºi
este inserat elementul curent aflat iniþial pe o poziþie i. Du- cazul cel mai favorabil atunci când poziþia elementului nu
pã determinarea poziþiei în care va fi inserat elementul cu- se modificã (ºirul este ordonat crescãtor).
rent, elementele cu valori mai mari sunt deplasate la stânga În tabelul 5 este prezentatã o statisticã a numãrului de
cu o poziþie. atribuiri ºi comparãri efectuate pentru cazul cel mai favo-
O versiune a pseudocodului acestui algoritm este: rabil, cazul mediu ºi cazul cel mai defavorabil.
Concluzii
Probabil cã v-aþi dat seama cã scopul acestui articol nu a
F i g u ra 8 : I n s e rt S o rt : c a zu l c e l ma i fost prezentarea unor metode de sortare care, de altfel,
favorabil - comparãri sunt cunoscute de marea majoritate a cititorilor revistei
noastre.
focus
Este evident faptul cã, în cazul cel mai favorabil, prima Am încercat sã arãtãm modul în care pot fi comparaþi
variantã este mai performantã. Aceasta se datoreazã faptu- diferiþi algoritmi care rezolvã aceeaºi problemã pentru a-l
lui cã o cãutare liniarã se realizeazã în timp O(1) pentru alege pe cel mai performant.
cazul cel mai favorabil în timp ce cãutarea binarã necesitã De asemenea, am dorit sã arãtãm importanþa detaliilor
un timp O(log n). de implementare. În funcþie de diferite alegeri pe care le
Pentru cazul mediu, graficul comparãrilor este prezen- facem putem îmbunãtãþi semnificativ performanþele.
tat în figura 9. Nu am prezentat demonstraþii riguroase ale diferitelor
afirmaþii pentru a nu încãrca articolul cu elemente mate-
matice mai greu de înþeles ºi, practic, neinteresante pentru
majoritatea cititorilor.
Am prezentat câteva metode intuitive prin care se pot
gãsi ordinele de complexitate ale diferitelor variante ale
unor algoritmi, fãrã a fi nevoie de un aparat matematic bine
pus la punct.
F i g u ra 9 : In se rtS o rt: c a zu l me d i u - c o mp a rã ri În practicã, sunt puþini cei care realizeazã demonstraþii
riguroase; majoritatea sunt mulþumiþi de demonstraþiile
În acest caz îºi face simþitã prezenþa perfomanþa supe- intuitive ºi în foarte puþine situaþii se dovedeºte cã astfel de
rioarã a algoritmului de cãutare binarã, faþã de algoritmul demonstraþii sunt eronate.
de cãutare liniarã. Chiar dacã pentru valori mici ale numã- Sfatul nostru este sã încercaþi întotdeauna sã folosiþi cea
rului de elemente ale ºirului, numãrul comparãrilor nu di- mai performantã variantã a unui algoritm, iar dacã existã
ferã foarte mult de la o variantã la alta, pentru valori mari mai mulþi algoritmi cu ajutorul cãrora poate fi rezolvatã
diferenþa este evidentã. problema cu care vã confruntaþi, sã îl alegeþi întotdeauna
Pentru cazul mediu, cãutarea liniarã are un timp de pe cel care duce la rezultate corecte în timpul cel mai scurt.
execuþie liniar (în medie, pentru determinarea poziþiei în Pentru aceasta nu este necesar sã vã complicaþi folo-
care trebuie inserat al i-lea element al vectorului, se efectu- sind calcule matematice complexe, ci puteþi desena doar
eazã i / 2 comparãri), în timp ce timpul de execuþie al câteva grafice ºi diferenþele între algoritmi vor fi evidente
cãutãrii binare este unul logaritmic. Aceasta este explicaþia în majoritatea cazurilor.
motivului pentru care cea de-a doua variantã este mai per- Chiar ºi simplele tabele pe care le-am folosit sunt sufi-
formantã. ciente pentru a vã da seama care dintre algoritmii sau va-
În figura 10 este prezentat graficul comparãrilor pen- riantele pe care le aveþi la dispoziþie va duce la obþinerea
tru cel mai defavorabil caz. celor mai bune performanþe.
Aºa cum aþi vãzut, detalii minore de implementare pot
îmbunãtãþi semnificativ performanþele. Aºa cum am arãtat
Ginfo nr. 1 - ianuarie 2001