– Sortare prin interclasare (merge sort) (Divide et impera)
– Sortare rapidă (quicksort) (Divide et impera) • Algoritmi de căutare – Căutare binară • Aplicaţii – maximul dintr-un vector, turnurile din Hanoi (3 tije: tija a are discuri aranjate in ordinea descrescătoare a diametrelor. Vrem să le mutăm pe tija b, folosind tija c), cmmdc(m,n) ab, n 1 H n, a, b, c H n 1, a, c, b , ab, H n 1, c, b, a , n 1 cmmdc n, m%n , n 0 cmmdc m, n m, n 0 08.12.21 Curs 6 – Divide et Impera 1 Curs 6 - Divide et Impera • Quicksort (Divide et impera + interschimbare) quicksort(inceput, sfarsit) O n log 2 n , în medie if(inceput >= sfarsit) stop//algoritmul se opreste dc vectorul e vid sau are un element i = inceput;//i porneste din stanga, inceput = pozPrimulElement j = sfarsit;//j porneste din dreapta, sfarsit = pozUltimulElement se alege un pivot (mijlocul segmentului de exemplu); elementele > pivotul se pun in dreapta iar cele < in stanga astfel: do{ while(v(i) < pivotul) i++; while(v(j) > pivotul) j--; //aici avem >= in staga si unul <= in dreapta, pt i<=j if(i<=j){ interschimbam numerele; i++; j--; } while (i < j) // pivotul va fi fixat pe pozitia corecta la sfarsitul acestei etape quicksort(inceput, j);//repet procedura pt v(inceput) : pivot(sau element anterior) quicksort(i, sfarsit); //repet procedura 08.12.21 pt pivot(sau Curs 6 – Divide et Impera element ce urmeaza lui) : 2 Curs 6 - Divide et Impera • Quicksort (Divide et impera + interschimbare) v = [7, -3, -1, 9, -6, 8] – sortare în ordine crescătoare I. [7, -3, -1, 9, -6, 8]: inceput = 0, sfarsit = 5 - [7, -3, -1, 9, -6, 8] [-6, -3, -1, 9, 7, 8]; i = 0, j = 4 pt prima parcurgere; interschimbare 7 cu -6; i++, j-- (i = 1, j = 3) - [-6, -3] + [9, 7, 8] II. [-6, -3]: inceput = 0, sfarsit = 1 - [-6, -3]; i = 0, j = 0 la prima parcurgere; i++, j-- (i = 1, j = -1) !!stop III. [9, 7, 8] : inceput = 3, sfarsit = 5 - [9, 7, 8]; i = 3,j = 4 la prima parcurgere;interschimbare 9 si 7; i++,j-- (i = 4, j = 3) IV. [9, 8] : inceput = 4, sfarsit = 5 - [9, 8]; i = 4,j = 5 la prima parcurgere;interschimbare 9 si 8; i++,j-- (i = 5, j = 4) !!stop
08.12.21 Curs 6 – Divide et Impera 3
Curs 6 - Divide et Impera • Mergesort (sortare cu interclasare) (Divide et impera + interclasare) mergesort(inceput, sfarsit) if(inceput >= sfarsit) stop//algoritmul se opreste dc vectorul e vid sau are un element mijloc = (inceput + sfarsit)/2; mergesort(inceput, mijloc);//repeta algoritmul pt jumatatile vectorului mergesort(mijloc+1, sfarsit); interclasare(inceput, mijloc, mijloc+1, sfarsit) O n O 2 k 2 O 2 k 1 2 k 2 2 O 2 k 2 2 k 1 2 k 22 O 2 2 2 O n log n k 2 k 2
08.12.21 Curs 6 – Divide et Impera 4
Curs 6 - Divide et Impera • Mergesort (sortare cu interclasare) (Divide et impera + interclasare) interclasare(inceput1, sfarsit1, inceput2, sfarsit2) i = 0;//parcurgere primul vector, v[inceput1:sfarsit1], ordonat crescator j = 0;//parcurgere al doilea vector, v[inceput2:sfarsit2], ordonat crescator k = 0;//parcurgere vector temporar, vTemp do{ if(v[i] < v[j]){ vTemp[k] = v[i]; i++;} else{ vTemp[k] = v[j]; j++;} k++; }while((i <= sfarsit1) && (j <= sfarsit2))//pana la epuizarea unui vector while(i <= sfarsit1){//au mai ramas elemente in primul vector si le adaugam vTemp[k] = v[i]; i++; k++;} while(j <= sfarsit2){//sau au mai ramas elemente in al doilea vector si le adaugam vTemp[k] = v[j]; j++; k++;} 08.12.21 Curs 6 – Divide et Impera 5 Curs 6 - Divide et Impera • Mergesort (sortare cu interclasare) (Divide et impera + interclasare) v = [7, -3, -1, 9, -6, 8] – sortare în ordine crescătoare I. [7, -3, -1, 9, -6, 8] - sortam v1 = [7, -3, -1] si v2 = [9, -6, 8] - interclasam v1 si v2 v = [-6, -3, -1, 7, 8, 9] II. [7, -3, -1] - sortam v11 = [7, -3] - interclasam v11 si [-1] v1 = [-3, -1, 7] III. [7, -3] - interclasam [7] si [-3] v11 = [-3, 7] IV. [9, -6, 8] - sortam v21 = [9, -6] - interclasam v21 si [8] v2 = [-6, 8, 9] V. [9, -6] - interclasam [9] si [-6] v21 = [-6, 9] 08.12.21 Curs 6 – Divide et Impera 6 Curs 6 - Divide et Impera • Binary search (căutare binară) (Divide et impera) – pentru vectori sortaţi – O(log2(n)) pozitie sortareBinara(inceput, sfarsit, n) mijloc = (inceput + sfarsit)/2; if(v(mijloc) == n) return mijloc; else if(inceput >= sfarsit) return -1!!! //algoritmul se opreste dc vectorul e vid sau daca are un singur element, diferit de cel cautat, returnand un cod de eroare if(v(mijloc)>n) pozitie = cautareBinara(inceput, mijloc-1); //cautam in jumatatea inferioara if(v(mijloc)<n) pozitie = cautareBinara(mijloc+1, sfarsit); //sau in jumatatea superioara return pozitie; 08.12.21 Curs 6 – Divide et Impera p comparaţii: n < 2p p = [log2(n)] + 1 7 Curs 6 - Divide et Impera • Binary search (căutare binară) (Divide et impera) – pentru vectori sortaţi - v = [-6, -3, -1, 7, 8, 9] (sortare în ordine crescătoare) - căutăm pe 7 I. [-6, -3, -1, 7, 8, 9]: inceput = 0, sfarsit = 5 - mijloc (pozitia 2): -1, 7 -1 - 7 > -1 - inceput sfarsit, cautam in vectorul ·[7, 8, 9] II. [7, 8, 9]: inceput = 3, sfarsit = 5 - mijloc (pozitia 4) : 8 , 7 8 - 7<8 - inceput sfarsit, cautam in vectorul ·[7] III. [7]: inceput = 3, sfarsit = 3 - mijloc (pozitia 3) : 7, 7 = 7, pozitie = mijloc !!!! stop
08.12.21 Curs 6 – Divide et Impera 8
Curs 6 - Divide et Impera • Binary search (căutare binară) (Divide et impera) – pentru vectori sortaţi - v = [-6, -3, -1, 7, 8, 9] (sortare în ordine crescătoare) - căutăm pe -7 I. [-6, -3, -1, 7, 8, 9]: inceput = 0, sfarsit = 5 - mijloc (pozitia 2): -1, -7 -1 - -7 > -1 - inceput sfarsit, cautam in vectorul ·[-6, -3, -1] II. [-6, -3, -1]: inceput = 0, sfarsit = 2 - mijloc (pozitia 1): -3, -7 -3 - -7 < -3 - inceput sfarsit, cautam in vectorul ·[-6] III. [-6]: inceput = 0, sfarsit = 0 - mijloc (pozitia 0): -7,- 7 -6 - inceput = sfarsit !!!! stop