Sunteți pe pagina 1din 13

Analiza complexităţii algoritmilor nerecursivi

Capitolul 4. Analiza complexită ții


algoritmilor nerecursivi
Din punctul de vedere al modului de definire a algoritmilor, un algoritm poate fi recursiv sau
nerecursiv. Vom începe studiul analizei complexității algoritmilor considerând cazul
algoritmilor nerecursivi.

La modul general, analiza complexității unui algoritm are ca scop estimarea volumului
resurselor de calcul necesare pentru execuția algoritmului:

• Complexitate statică: spațiul de memorie necesar pentru stocarea datelor care se


prelucrează
• Complexitate dinamică: timpul necesar pentru execuția tuturor prelucrărilor
specificate de instrucțiunile algoritmului

Dacă în anii 1990 spațiul de memorie utilizat de un program era o resursă critică datorită
capacității reduse a memoriilor calculatoarelor din acea vreme, astăzi aceast factor este mai
puțin important. Calculatoarele actuale au suficientă memorie pentru procesările obișnuite.

Kevin Kelly in The New York Times, “the whole written literature of the humanity, from the
appearence of writting and in all languages, does not go over 50 petabytes” (pentabyte =
1015bytes).

Bineînțeles ca volumul resurselor necesare depinde de volumul datelor de intrare. Mai precis,
dimensiunea datelor de intrare este calculată după numărul de biți necesari pentru stocarea
datelor. Mărimea unei instanțe, notată cu |x| este dată de numărul de biți necesari pentru
stocarea lui x. Astfel, când vorbim de stocare, |x| este numărul de elemente care se sortează. La
algoritmii numerici, |x| este valoarea numerică a instanței x.

Dintre cele două resurse de calcul, cea critică este timpul de execuție. Acesta depinde de
numărul de operații care trebuie efectuate și de dimensiunea datelor de intrare. Deci, timpul de
execuție diferă de la rulare la alta.

Figura 12. Importanţa resursei timp


Analiza complexităţii algoritmilor nerecursivi

Exemplificare: Importanța alegerii unei variante optime de calcul.

Algoritmul pentru determinarea divizorilor proprii ai unui număr


Varianta costisitoare Varianta îmbunătățită Varianta optimă
for i ← 2, n do for i ← 2, n/2 do for i ← 2, √ do
if (x % i = 0) if (x % i = 0) if (x % i = 0)
scrie i scrie i scrie i
endif endif endif
endfor endfor endfor

Având in vedere că pentru seturi de date de intrare diferite, un același algoritm operează în
timpi de execuție diferiți, analiza complexității algoritmilor tratează cu precădere două cazuri:

• Cazul cel mai defavorabil are durata maximă de execuție


• Cazul mediu – se consideră drept raportul între suma timpilor necesari execuției tuturor
seturilor de date posibile și numărul acestora. Însă, marea majoritate a algoritmilor au
un număr nelimitat de seturi de date, deci acest caz nu poate fi analizat cu exactitate,
cautându-se o aproximare a lui.

Un algoritm este considerat eficient dacă necesită un volum rezonabil de resurse de calcul.

4.1 Timpul de execuție


În continuare, vom nota cu T(|x|) timpul de execuție al unui algoritm relativ la instanța x ∈ I.
Pentru a estima timpul de execuție este necesar a se stabili un model de calcul și o unitate de
măsură. Vom considera în cele ce urmează modelul de calcul cu acces aleatoriu:

• Toate instrucțiunile sunt executate secvențial


• Fiecărei operații elementare i se alocă o unitate de timp, indiferent de tipul operanzilor4.
• Timpul de acces la informație nu este contorizat

Unitatea de măsură pe baza căreia vom calcula eficiența teoretică a unui algoritm derivă din
principiul invariației potrivit căruia două implementări diferite ale aceluiași algoritm nu diferă
în eficiență cu mai mult decât o constantă multiplicativă. Adică, presupunând ca avem două
implementări de T1(|x|) respectiv T2(|x|) secunde pentru un caz de mărime |x|, există o constantă
pozitivă c astfel încât T1(|x|) < cT2(|x|), pentru orice |x| suficient de mare.

Dacă un algoritm necesită un timp de ordin |x| vom spune că necesită un timp liniar sau că este
un algoritm liniar. Similar, un algoritm este pătratic, cubic, polinomial sau exponențial dacă
necesită timp de ordinul |x|2, |x|3, |x|k respectiv k|x|, unde k este o constantă.

Exemplu. Să se analizeze algoritmul care determină factorialul unui număr n, adică calculează
n! = n(n-1)(n-2) ... 2⋅1

4
Procesoarele actuale pot executa miliarde de operații pe secundă. Astfel, un număr constant de unități de
timp în plus sau în minus nu impactează ordinul de creștere al timpului de execuție.

48
Analiza complexităţii algoritmilor nerecursivi

Algoritm Cost

function factorial(n)
fact ← 1 1
i←2 1
while (i <= n) do n
fact ← fact × i 2(n-1)
i ← i +1 2(n-1)
endwhile
return fact 1
endfunction

Numărul total de operatii = 1+ 1 + (n-1)×4 + 1 = 4n – 2, unde prin valoarea 1 simbolizăm o


unitate de timp.

4.2 Cazuri de analiză


Asa cum s-a mai precizat, timpul de execuție depinde în mod categoric de instrucțiunile
algoritmului dar și de dimensiunea și proprietățile datelor de intrare. Din acest motiv, timpul
de execuție al unui același algoritm poate varia. Astfel, în raport cu proprietățile datelor de
intrare, în literatura de specialitate au fost introduse trei cazuri de analiză:

- Cazul cel mai favorabil


- Cazul cel mai defavorabil
- Cazul mediu

Cazul cel mai favorabil (CCMF) furnizează o margine inferioară a timpului de execuție. Acest caz e mai
puțin util în analiza eficienței algoritmilor însă permite identificarea algoritmilor ineficienți – acei
algoritmi care au un timp de execuție mare și în cel mai favorabil caz.

Cazul cel mai defavorabil (CCMD) reprezintă cel mai mare timp de execuție furnizînd limita superioară
pentru acesta. În analiza algoritmilor, marginea superioară este mai importantă decât marginea
inferioară.

În practică aceste cazuri extreme (CCMF și CCMD) se întălnesc rar, astfel că analiza acestora
nu furnizează suficientă informație despre comportamentul algoritmului studiat. Însă pot
delimita zona în care poate varia timpul de execuție al algoritmului.

49
Analiza complexităţii algoritmilor nerecursivi

Cazul mediu (CM) se bazează pe cunoașterea distribuției de probabilitate a datelor de intrare, adică
pe estimarea probabilității de apariție a fiecăreia din instanțele posibile. Timpul mediu de execuție
este valoarea medie (în sens statistic) a timpilor de execuție corespunzători diferitelor instanțe.

Timpul mediu de execuție reprezintă o valoare medie a timpilor de execuție calculată în raport cu
distribuția de probabilitate a datelor de intrare.

Stabilirea acestei distribuții de probabilitate presupune împărțirea mulțimii instanțelor posibile


în clase astfel încât pentru instanțe din aceeași clasă numărul de operații efectuate să fie mereu
același.

Ipoteze de estimare pentru cazul mediu:

- Datele de intrare pot fi grupate în clase după timpii lor de execuție


- Există un număr finit de astfel de clase (m)
- Probabilitatea de aparitie a unor date din clasa k este Pk
- Timpul de execuție al algoritmului pentru date de intrare aparținând clasei k este Tk

În aceste ipoteze de calcul, timpul mediu de execuție este:

Tmediu(|x|) = P1T1(|x|) + ... + PmTm(|x|)

Dacă probabilitatea de apariție este aceeași pentru toate clasele (cazuri echiprobabile) atunci:

Tmediu(|x|) = ∑ (| |)

Observație. Datorită dificultăților ce pot interveni în stabilirea timpului mediu și mai ales,
datorită faptului că, în cele mai multe cazuri, acesta diferă de timpul în cazul cel mai defavorabil
doar prin valori ale constantelor implicate, analiza algoritmilor se rezumă la estimarea timpului
de execuție pentru cazul cel mai defavorabil.

4.3 Etapele analizei algoritmilor nerecursivi


Nu este întotdeauna necesar să se contorizeze toate costurile instrucțiunilor unui algoritm
pentru a se determina timpul de execuție. De regulă, este suficient să se estimeze doar numărul
de executări ale operației dominante. Vom numi în cele ce urmează operație dominantă acea
instrucțiune cu cel mai mare cost sau cea mai repetitivă.

Analiza algoritmilor nerecursivi implică următorii pași:


1. Se stabilește dimensiunea datelor de intrare
2. Se identifică operația dominantă a algoritmului și numărul de executări ale acesteia
3. Se determină expresia matematică a timpului de execuție în funcție de dimensiunea datelor de
intrare: T(|x|), x – data de intrare. Dacă expresia matematică diferă în funcție de valorile (proprietățile)

50
Analiza complexităţii algoritmilor nerecursivi

datelor de intrare se face analiza pe cele 3 cazuri: CCMF, CCMD și CM. Dacă TCCMF(|x|) ≠ TCCMD(|x|) se
determină și TCM(|x|).
4. Expresia matematică a lui T(|x|) sau, pentru algoritmi care depind de proprietățile datelor de intrare,
a lui TCM(|x|) (după caz se poate calcula direct TCCMD(|x|)) dă ordinul de complexitate al algoritmului.

Exemplificare. Sortarea prin inserție

Intrare: un vector de elemente x = v[1] ... v[n]

Ieșire: o permutare v[σ(1)], ..., v[σ(n)] astfel încât: v[σ(1)] < ... < v[σ(n)]

Dimensiunea problemei: |v[1…n]| = n

Algoritm Timp execuție Repetări


1. for i ← 2,n do c1 + c2n+c3(n-1) 1
2. key ← v[i] c4 n-1
3. j ← i-1 c5 n -1
4. while((j>0)and(v[j]> key))do c6 ∑ ( ( ) +1)
c7 ∑ ()
5. v[j+1] ← v[j]
c8 ∑ ()
6. j ← j-1
7. endwhile
8. v[j+1] ← key c9 n-1
9. endfor

Să se considere pentru studiu de caz vectorul (8, 1, 4, 9, 2, 6)

(8, 1, 4, 9, 2, 6) → (1, 8, 4, 9, 2, 6) → (1, 4, 8, 9, 2, 6) → (1, 4, 8, 9, 2, 6) → (1, 2, 4, 8, 9, 6) →


(1, 2, 4, 6, 8, 9)

...

T(n) = c1 + c2n + c3(n-1) + c4(n-1) + c5(n-1) + c6∑ ( ( ) + 1) + c7 ∑ ( ) + c8 ∑ ()


+ c9(n-1). Cum orice sumă finită de constante (unități de timp) reprezintă tot o constantă (se
realizează tot într-o unitate de timp) vom nota cu ki sume de constante din egalitatea de mai
sus.

CCMF: tabloul este sortat ⇒ δ(i)=0, i=2, ⇒ TCCMF(n) = c1 + c2n + c3(n-1) + c4(n-1) + c5(n-
1) + c6∑ 1 + c9(n-1) = k1 + k2n.

CCMD: tabloul este sortat în ordine inversă (descrescătoare) ⇒

()= 1 ă 2
i=2, ; i=3, ( ) = ; ...
0 0

deci obținem δ(i)=i-1, i=2, ⇒ TCCMD(n) = c1 + c2n + c3(n-1) + c4(n-1) + c5(n-1) + c6∑ +
c7 ∑ ( − 1) + c8 ∑ ( − 1) + c9(n-1) = k1 + k2n + k3n2

51
Analiza complexităţii algoritmilor nerecursivi

CM: toate permutările au aceeași probabilitate de apariție. Timpul de execuție în acest caz are
aceeași expresie ca în cazul CCMD, deoarece în medie δ(i)=i/2 (în general, pentru un element
oarecare v[i] avem în medie jumătate de elemente din vector mai mari decât el și jumatate mai
mici, deci în medie ar trebui să parcurgem jumatate de vectorul v[1... i-1] pentru a-l insera în
poziția corectă.

Exemplificare. Considerăm problema apartenenței unui element la un vector (căutarea liniară).


Considerăm v[1...n] un vector de n elemente și cautăm să reținem în variabila gasit aparteneța
elementului x la vector.

Algoritm Timp Repetări


execuție
1. gasit ← false c1 1
2. i ← 1 c2 1
3. while (!gasit) and (i<=n) do c3 δ1(n)+1
4. if (v[i]=x) then c4 δ1(n)
5. gasit ← true c5 δ2(n)
6. endif
7. i ← i+1 c6 δ1(n)
8. endwhile
9. return gasit

Și în acest caz timpul de execuție depinde de valorile din tabloul de intrare. Vom face o analiză
pe toate cele trei cazuri:

Cazul cel mai favorabil CCMF când elementul x aparține vectorului și v[1] = x

Cazul mediu CM când elementul x aparține vectorului și v[k] = x, k >1

Cazul cel mai defavorabil CCMD când elementul x nu aparține vectorului.

CCMF CM CCMD
δ1(n) 1 k n
δ2(n) 1 1 0

Marginile timpului de execuție sunt date de cazul cel mai favorabil (limita inferioară) și cazul
cel mai defavorabil (limita superioară).

c1+ c2 + c3 + c4 + c5 ≤ T(|x|) ≤ c1 + c2 + (n+1)c3 + nc4 + nc6 ⇒ k1 ≤ T(|x|) ≤ k2n + k3

unde |x| notează dimensiunea datelor de intrare, care în acest caz este n.

Obținem că limita inferioară este o constantă și că limita superioară depinde liniar de


dimensiunea problemei.

Pentru calcularea timpului mediu, ipotezele de calcul sunt:

- Probabilitatea ca x să fie în tablou este p


52
Analiza complexităţii algoritmilor nerecursivi

- Probabilitatea ca x să nu fie în tablou este 1 – p


- Probabilitatea ca x să se afle pe poziția k în tablou este p/n.

Complexitatea pentru cazul mediu se definește ca fiind probabilitatea ca elementul x să fie în


tablou (x = v[k], ! = """""
1, ) + probabilitatea ca elementul x să nu fie în tablou.
$ $ $
Tmediu(n) = # (%&1' = ) + (%&2' = ) + ⋯ + (%& ' = )) + (1 −
%& ' ≠ $ $ $ $ $
*) + - = # ∙ 1 + ∙ 2 + ⋯ + ∙ ) + (1 − *) ∙ = #1 − ) + .
= """""
1,

Pentru p = 0.5 obținem Tmediu(n) = 3/4n + ¼.

Deci timpul mediu de execuție pentru algoritmul de căutare secvențială depinde liniar de
dimensiunea datelor de intrare.

Din formula timpului mediu putem să determinăm formulele pentru timpul de execuție în cazul
în care elementul se află în tablou: p=1:

+1
/∈1& … ' ( )=
2
ceea ce se poate interpreta astfel: în cazul aparteneței elementului la vector, algoritmul parcurge
în medie jumătate din vector.

În cazul non-aparteneței elementului la vector (cazul cel mai defavorabil) avem p=0, ceea ce
implică:

/∉1& … ' ( )= 3345 ( )=n

4.4 Ordinul de creștere


Scopul principal al analizei eficienței algoritmilor este acela de a identifica modul în care
timpul de execuție crește odata cu creșterea dimensiunii problemei. Pentru aceasta trebuie să
se identifice:

- Ordinul de creștere al timpului de execuție


- Clasa de eficiență (complexitatea) algoritmului

În analiza expresiei timpului de execuție trebuie să se identifice expresia termenului dominant.

Definiție. Numim termen dominant, termenul din expresia timpului de execuție care devine
semnificativ mai mare când dimensiunea problemei crește. Astfel, el dictează comportamentul
algoritmului, pe date de intrare de dimensiune mare.

Exemple de expresii pentru timp de execuție (în bold este scris termenul dominant)

53
Analiza complexităţii algoritmilor nerecursivi

- T1(n) = an+b
- T2(n) = alogn+b
- T3(n) = an2 + bn + c
- T4(n) = an + bn + c

Definiție. Ordinul de creștere caracterizează creșterea termenului dominant din expresia timpului de
execuție în raport cu dimensiunea problemei. Mai precis, ordinul de creștere cuantifică creșterea
termenului dominant când dimensiunea problemei crește de k ori.

Exemple:

TD1(n) = an ⇒ TD1 (kn)= kan = kTD1(n) – creștere liniară

TD2(n) = alogn ⇒ TD2 (kn) = alog(kn) = a(logk + logn) = alogk + TD2(n) – creștere logaritmică

TD3(n) = an2 ⇒ TD3 (kn) = a(kn)2 = k2⋅ an2 = k2TD3(n) – creștere pătratică

TD4(n) = an ⇒ TD4 (kn) = akn = (an)k = TD4(n)k – creștere exponențială

Prin intermediul ordinului de creștere putem compara doi algoritmi

- Compararea se realizează pe seturi de date de dimensiuni mari valori mari (analiza


asimptotică)
- Algoritmul cu ordinul de creștere mai mic este mai eficient
;5< ( )
- Pentru a compara ordinele de creștere a doi timpi de execuție se calculează lim ,
→: ;5= ( )
unde TD1(n) și TD2(n) sunt termenii dominanți din expresiile matematice ale timpilor
de execuție corespunzători celor doi algoritmi:
o Dacă lim = 0, atunci Algoritmul 1 are ordinul de creștere mai mic decât
Algoritmul 2
o Dacă lim = c, c>0 – constantă, ambii algoritmi au același ordin de creștere
o Dacă lim = ∞, Algoritmul 2 are ordinul de creștere mai mic decât Algoritmul 1

Formule utile pentru determinarea ordinului de creștere

∑ 1= – sumă de constantă, complexitate liniară

( > )
∑ = - sumă liniară, complexitate pătratică

( > )( > )
12 + 22 + … + n2 = ?
= @n3 + n2 + ?n – complexitate cubică

BC<
∑ A
= - complexitate polinomială
A>

A DC< E
∑ ! = - complexitate exponențială (nu contează baza)
AE

54
Analiza complexităţii algoritmilor nerecursivi

∑ ( ±G )=∑ ±∑ G

∑ H = H∑

∑ A1 = −!+1

ln(∏A A) = ∑A ln( A)

55
Analiza complexităţii algoritmilor nerecursivi

4.5 Fişa de laborator


Fundamente teoretice
Analiza complexității algoritmilor
o Complexitate statică
o Complexitate dinamică
Timp de execuție. Modelul de calcul cu acces aleator
Cazul cel mai favorabil
Cazul cel mai defavorabil
Cazul mediu
Ipoteze de estimare a cazului mediu. Cazuri echiprobabile
Etapele analizei algoritmilor nerecursivi
Operație dominantă
Termen dominant
Ordinul de creștere
o Exemple de creșteri
Compararea algoritmilor în baza ordinului de creștere

Exerciţii
Exercițiu 1. Considerăm problema calculării sumei primelor n numere naturale ∑ .
Dimensiunea acestei probleme poate fi considerată n.

Algoritm Timp execuție Repetări


1. suma ← 0 c1 1
2. i ← 0 c2 1
3. while (i < n) do c3 n +1
4. i ← i+1 c4 n
c5 n
5. suma ← suma + i
6. endwhile
7. return suma

Obținem că T(n) = c1 + c2 + (n-1)c3 + nc4 + nc5 = nk1 + k2 deci timpul de execuție depinde
liniar de dimensiunea datelor de intrare, adică de n.

Exercițiu 2. Considerăm problema înmulțirii a două matrici A(m,n) și B(n, p). În acest caz
dimensiunea datelor de intrare este data de tuplul (m, n, p).

Algoritm Timp execuție Repetări


1. for i ← 1, m do c1 + (m+1)c2 + mc3 1
2. for j ← 1, p do c4 + (p+1)c5 + pc6 m
3. c[i,j] ← 0 c7 mp
Analiza complexităţii algoritmilor nerecursivi

4. for k ← 1, n do c8 + (p+1)c9 + pc10 mp


5. c[i,j]←c[i,j]+ a[i,k]*b[k,j] c5 mpn
6. endfor
7. endfor
8. endfor

Se poate lesne verifica că T(m, p, n) = mnpk1 + mpk2 + mk3 + k4.

Exercițiu 3. Considerăm problema determinării valorii minime dintr-un vector de n elemente.


Dimensiunea problemei este dată de numărul de elemente din vector, |vect[1...n]| = n.

Algoritm Timp execuție Repetări


1. min ← vect[1] c1 1
2. for i ← 2, n do c2 + nc3 + (n-1)c4 1
3. if (min > vect[i]) then c5 n-1
4. min ← vect[i] c6 δ(n)
5. endif
6. endfor
7. return min

Spre deosebire de cazurile anterioare, timpul de execuție al acestui algoritm nu poate fi stabilit
cu certitudine, el depinzând de valorile tabloului de intrare. Cazul cel mai favorabil (CCMF)
este atunci când minumul se află pe prima poziție in vector. În acest caz intrucțiunea 4. nu se
va mai executa și avem δ(n) = 0.

Cazul cel mai defavorabil (CCMD) este când vectorul e sortat descrescător deci minimul se
află pe ultima poziție în tablou și instrucțiunea 4. se execută de un număr maxim de ori. În acest
caz δ(n) = n-1. În ambele cazuri, atât limita inferioară cît și limita superioară depind liniar de
dimensiunea problemei, deci T(n) = k1n + k2.

Exercițiu 4. Să se definească un algoritm care stabileste dacă un vector are numai elemente
distincte.

Algoritm Timp Repetări


execuție
1. i ← 1 c1 1
2. j ← 2 c2 1
3. gasit ← false c3 1
4. while (i<n) and (!gasit) do c4 δ1(n)+1
5. j ← i+1 c5 δ1(n)
6. while (j<=n) and (!gasit) c6 δ2(n)+1
7. if (v[i] = v[j]) then c7 δ2(n)
8. gasit ← true c8 δ3(n)
9. endif
10. j ← j+1 c8 δ2(n)
11. endwhile

57
Analiza complexităţii algoritmilor nerecursivi

12. i ← i+1 c9 δ1(n)


13. endwhile
14. return gasit

Operația dominantă a algoritmului este testarea egalității de pe rândul 7. deoarece este cea mai
imbricată operație a algoritmului (cea mai repetitivă).

CCMF (depinde de valorile din vectorul v): primele două elemente sunt egale

CCMD (depinde de valorile din vectorul v): avem două posibilități:

- vectorul v are numai elemente distincte (δ3(n) = 0)


- ultimele două elemente din vector sunt egale (δ3(n) = 1)
( E )
În ambele sitații CCMD avem: δ2(n) = (n-1) + ... + 1 =

CCMF CCMD CM
δ1(n) 1 n-1 (n-1)/2
E E
( − )
δ2(n) 1 K( − ) K
2
δ3(n) 1 1 sau 0 1

Exercițiu 5. Să se scrie algoritmul de determinare a numărului de biți din reprezentarea binară


a unui întreg.

Algoritm Timp execuție Repetări


1. no ← 1 c1 1
2. while (n>1) do c2 log2n +1
3. no ← no+1 c3 log2n
4. n ← n/2 c4 log2n
5. endwhile
6. return no

Exercițiu 6. Să se definească și să se analizeze algoritmul de căutare al unui element într-un


vector folosind metoda fanionului.

Exercițiu 7. Să se analizeze timpul de execuție al algoritmului de sortare prin interschimbare


dat în tabelul de mai jos.

Algoritm Timp Repetări5


execuție
1. for i ← 1, n-1 do k1(n-1) 1

5
Repetările în cazul instrucţiunilor FOR contorizează numărul de executări pentru incrementările variabilelor
contor.

58
Analiza complexităţii algoritmilor nerecursivi

2. for j ← i+1, n do k2 ∑ E
( − )
3. if (v[i]>v[j]) then c3 ∑ E
( − )
4. v[i] ↔ v[j] k4 δ(n)
5. endif
6. endfor
7. endfor

T(n) = k1(n-1) + k2 ∑ E
( − ) + c3∑ E
( − ) + k4 δ(n).

Funcţia δ(n) în raport cu proprietăţile datelor de intrare este:

CCMF CCMD CM
(vectorul e sortat crescător) (vectorul e sortat descrescător)
E E
( − )
δ(n) 0 K( − ) K
2

Cazul cel mai defavorabil pentru funcţia δ(n) corespunde numărului de executări ale
instrucţiunii IF care este operaţia dominantă a algoritmului, deci acest algoritm are o
complexitate pătratică.

Obţinem că în cazul cel mai defavorabil (CCMD) ca și în cazul mediu (CM) δ(n) = n(n-1)/2,
deci ordin pătratic de creştere pentru termenul dominant.

Exerciţiul 8. Analizaţi complexitatea algoritmului de sortare prin inserţie.

Exerciţiul 9. Analizaţi complexitatea algoritmului Quicksort.

Discuţie. Complexitatea algoritmului QuickSort în cazul cel mai defavorabil este O(n2) iar în
cazul mediu este O(n⋅logn).

Algoritmul QuickSort încearcă partiţionarea vectorului în doi vectori mai mici, până când
întregul vector este sortat (algoritmul QuickSort este de tipul Divide et Impera).

La fiecare apel al funcţiei se încearcă poziţionarea elementelor mai mici în partea stângă şi a
elementelor mai mari în partea dreapta (dacă se implementează sortarea crescătoare).

Cazul cel mai defavorabil, ca la toţi algoritmii de sortare corespunde situaţiei în care vectorul
este sortat descrescător. Deci în acest caz toate elementele din partea dreaptă trebuie aduse în
partea stângă ⇒ n/2 pași, în total n⋅ n/2 pași ⇒ complexitate pătratică.

Dacă elemente au o probabilitate medie de a nu se afla în ordinea dorită atunci vom efectua
logn mutări dintr-o parte în alta, deci complexitatea algoritmului este O(n⋅ log n).

59

S-ar putea să vă placă și