Documente Academic
Documente Profesional
Documente Cultură
Cursul06 ATP2022
Cursul06 ATP2022
Algoritmi și tehnici de
programare
Cursul 6
+
Cuprins
◼ Sortare rapidă
◼ Sortarea Shell
◼ Sortarea Heap
◼ Sortare pe grupe
◼ Pointeri la funcții
+
Sortarea rapidă
◼ Algoritmul
de sortare rapidă, ca de altfel şi algoritmul de
sortare prin interclasare, se bazează pe “divide şi
stăpâneşte”.
◼ Algoritmul:
4 6 1 3 5 2 7
+
Sortarea rapidă
4 6 1 3 5 2 7
2 6 1 3 5 4 7
+
Sortarea rapidă
2 6 1 3 5 4 7
2 3 1 6 5 4 7
+
Sortarea rapidă
2 3 1 6 5 4 7
+
Sortarea rapidă
Vector sortat
1 2 3 4 5 6 7
+
Sortarea rapidă
❑ i = p; j = u; m=mijloc
pasul curent:
❑ daca a[i] < m atunci i = i+1
❑ daca a[j] > m atunci j = j-1
❑ daca a[i] > m > a[j] si i < j atunci
▪ schimba(a[i], a[j])
▪ i = i+1
▪ j = j-1
pasul curent se execută atât timp cât i <= j.
+
Sortarea rapidă
void poz(int v[], int stanga, int dreapta, int *s, int *d)
{
int i, j, mijloc, aux; // variabilele
i = stanga; // initializarea indicilor
j = dreapta;
mijloc = v[(stanga + dreapta) / 2]; // initializarea variabilei - pivot
while (i <= j)
{
while (v[i] < mijloc) // apropierea i-ului de mijloc
i = i + 1;
while (v[j] > mijloc) // apropierea j-ului de mijloc
j = j - 1;
if (i <= j) //conditia efectuarii operatiei de interschimbare
{
aux = v[i];
v[i] = v[j]; // operatia de interschimbare
v[j] = aux;
i = i + 1;
j = j - 1;
}
}
*s = i; *d = j;
}
+
Sortarea rapidă
void quick(int *v, int p, int u)
{
int i,j;
if (p<u)
{
poz(v, p, u, &i,&j);
if (p<j) quick(x, p, j);
if (i<u) quick(x, i, u);
}
}
+
Sortarea Shell
◼În 1959 D.L. Shell a propus un algoritm de ordonare bazat pe
metoda de sortare prin inserţie directă.
◼ Trecem la 35.
◼ Încercăm să îl deplasăm cu 5 poziţii spre stânga şi vedem că acolo se
află 95, un număr mai mare.
◼ Ca urmare facem efectiv deplasarea, iar 95 trece în locul lui 35.
◼ Obţinem:
◼ 32 35 16 82 24 66 95 19 75 54 40
+
Sortarea Shell
◼ Se consideră un şir descrescător de numere naturale, numite incremenţi
dintre care ultimul, incn, este 1:
◼ inc1 > inc2 > … > inci > inci+1 > … > incn = 1.
◼ v[1], v[incm+1],
◼ v[2], v[incm+2],
◼
◼ v[incm], v[2incm].
Apel:
int n;
double x[100]
sort_shell(x,n);
+
Sortare prin numărare
◼ Pentru fiecare element v[i] numărăm câte elemente sunt mai mici
ca el, aceste numere reţinându-le în vectorul num:
◼ num=(3, 0, 1, 4, 2) se reconstitue vect V astfel:
◼ v[num[0]]=temp[0]; v[num[1]]=temp[1]...
◼ Sortare Heap
◼ Aranjare heap
◼ Construire heap
+
Sortarea Heap
◼ La fiecare pas, cel mai mic element din tablou este gasit si mutat
in spatele tabloului, fiind ignorat de pasii urmatori, care vor continua
pe restul tabloului
◼ vi ≤ v2·i+1
◼ Evident, pentru valori ale lui i mai mari decat n/2 nu se pune
problema indeplinirii conditiilor de mai sus
+
Sortarea Heap
v1
v2 v3
v4 v5 v6 v7
v8 v9
+
Sortarea Heap
◼ Astfel, v2 si v3 sunt mai mari sau egale cu v1, iar v4 si v5 sunt mai mari sau
egale cu v2, s. a. m. d.
◼ Aducerea unui tablou la forma de ansamblu se face urmarind situatii cum este
cea descrisa mai jos:
5 1
8 6 4 3
7 2
5 1
2 6 4 3
7 8
◼ Urmatorul nod neterminal este 1 (nodul 5 este pe acelasi nivel, dar il alegem
intotdeauna pe cel mai din dreapta in astfel de cazuri)
◼ Nodul 1 este mai mic decat fiii sai, deci nu va face obiectul vreunei interschimbari
◼ Trecand la nodul 5, acesta nu indeplineste conditiile, ca atare va fi interschimbat cu
cel mai mic fiu al sau, anume 2
+
Sortarea Heap
9
2 1
5 6 4 3
7 8
◼ Inainte de a trece la noul nod neterminal, verificam ca ultimul nod interschimbat (5)
sa indeplineasca conditia referitoare la fiii sai (7 si 8) – se observa ca o indeplineste
◼ Noul nod neterminal este 9
◼ Acesta nu indeplineste conditiile, fiind mai mare si decat 2 si decat 1, ca atare, 9 va
fi interschimbat cu cel mai mic, deci cu 1
+
Sortarea Heap
1
2 9
5 6 4 3
7 8
2 3
5 6 4 9
7 8
◼ 9 a ajuns pe un nivel terminal (nu mai are fii) deci nu mai continuam in jos
◼ In acest moment, tabloul a ajuns la forma de ansamblu, fiecare nod avand cheia
mai mica sau egala decat cheile fiilor sai
◼ Cel mai mic element al tabloului a ajuns pe post de radacina
◼ Interschimbam radacina cu ultimul element al tabloului, adica 1 cu 8
+
Sortarea Heap
8
2 3
5 6 4 9
7 1
◼ Elementul minim (1) se elimina si se adauga la un tablou auxiliar, initial vid, care
va contine la final elementele sortate
2 3
5 6 4 9
7 1
Index: 0 1 2 3 4 5 6 7 8
Tablou auxiliar: 1 - - - - - - - -
+
Sortarea Heap
8
2 3
5 6 4 9
8 3
5 6 4 9
5 3
8 6 4 9
5 3
7 6 4 9
◼ Tabloul a devenit ansamblu, cel mai mic element din tablou ajungand pe post de radacina
Sortarea Heap
8
5 3
7 6 4 9
5 3
7 6 4 9
2
Index: 0 1 2 3 4 5 6 7 8
Tablou auxiliar: 1 2 - - - - - - -
+
Sortarea Heap
}
Exemplu de apel:
double *v; int n;
heapSort(v,n);
+
Sortare pe grupe (bucket sort)
◼ Bucket Sort sau sortare compartimentată este un algoritm folosit pentru sortarea unui
vector cu n elemente ale cărui valori sunt uniform distribuite pe un interval [a,b].
◼ n = lungime[A]
◼ pentru i = 1, n executa
Exemplu:
(a) Tabloul de intrare A[1::10].
(b) Tabloul B[0::9] al listelor (reprezentând grupele)
sortate dupa linia a cincea a algoritmului. Grupa i
cuprinde valorile din intervalul [i=10; (i + 1)=10).
Iesirea sortata consta dintr-o concatenare în ordine a
listelor B [0], B [1] ; :::;B [9].
+
Sortare pe baza cifrelor (radix sort)
◼ Radix Sort este un algoritm de sortare care ţine cont de cifre individuale ale elementelor
sortate.
◼ Există două tipuri de astfel de sortare: LSD (least significant digit) şi MSD (most significant
digit). LSD procesează reprezentările dinspre cea mai puţin semnificativă cifră spre cea mai
semnificativă, iar MSD invers.
◼ O versiune simplă a radix sort este cea care foloseşte 10 cozi (câte una pentru fiecare cifră
de la 0 la 9). Aceste cozi vor reţine la fiecare pas numerele care au cifra corespunzătoare
rangului curent. După această împărţire, elementele se scot din cozi în ordinea crescătoare
a indicelui cozii (de la 0 la 9), şi se reţin într-un vector (care devine noua secvenţă de
sortat).
◼ Exemplu:
◼ Secvenţa iniţială:
◼ 170, 45, 75, 90, 2, 24, 802, 66
◼ 170, 045, 075, 090, 002, 024, 802, 066
+
Sortare pe baza cifrelor (radix sort)
◼ Vector sortat:
◼ 002,024, 045, 075, 090, 170, 802
+
Sortari - complexitate
Algoritm de
Cel mai bun caz Cazul obișnuit Cel mai rău caz
sortare
Bule 𝑂 𝑛 𝑂 𝑛2 𝑂 𝑛2
Selectie 𝑂 𝑛2 𝑂 𝑛2 𝑂 𝑛2
Inserare 𝑂 𝑛 𝑂 𝑛2 𝑂 𝑛2
Shell 𝑂 𝑛 ≥ 𝑂 𝑛 ∙ log 𝑛 𝑂 𝑛2
Prin numărare 𝑂 𝑛 𝑂 𝑛 𝑂 𝑛
• de complexitate;
• de cantitatea de memorie necesară;
• de dificultate.
+
Sortari - clasificare
După cantitatea de memorie utilizată:
a) metode directe (sortează vectorul în spaţiul său de
memorie)
b) metode indirecte (necesită vector auxiliar)
tip_returnat nume_functie(lista_parametri);
tip_returnat (*nume_variabila_pointer_funcție)(lista_parametri);
+
Pointeri la funcții
(*pf)(listă_parametri_actuali);
+
Pointeri la funcții
#include <stdio.h>
/* Definim doua functii cu doi parametri de tip int si care returneaza un int. */
un_pointer = &o_functie;
rez=o_functie(3, 9);
printf("rez=%d\n", rez);
+
Pointeri la funcții
/* Invocam prima functie prin intermediul pointerului. In loc de numele functiei
folosim operatorul *. */
printf("rez=%d\n", rez);
un_pointer = &alta_functie;
rez=alta_functie(5, 25);
printf("rez=%d\n", rez);
printf("rez=%d\n", rez);
}
+
Pointeri la funcții
◼ Tipul
sortării se stabilește printr-o funcție care este trimisă
ca parametru funcției de sortare
Apel
void main()
{
int x[10], n;
...
sorteaza(x, n, asc);
sau
sorteaza(x, n, desc);
}
+
Pointeri la funcții.
Metoda bisectiei.
◼ Metoda bisecţiei pentru rezolvarea unei ecuaţii
transcendenete
a sol b
+
Pointeri la funcții
void main()
{
float a, b, eps, x;
int cod;
long n;
float(*functie)(float);
printf("captele intervalului");
scanf("%f %f", &a, &b);
printf("eroarea admisa:");
scanf("%f", &eps);
printf("numarul maxim de iterati:");
scanf("%li", &n);
functie = fct;//functie = fct1;
bisectie(a, b, n, eps, functie, &cod, &x);
if (cod == 0) printf("nu se poate calcula solutia aproximativa");
else printf("solutia aproximativa este:%5.2f", x);
/*cod = bisectie1(a, b, n, eps, functie, &x);
if (cod == 0) printf("nu se poate calcula solutia aproximativa");
else printf("solutia aproximativa este:%5.2f", x);*/
}
+
Bibliografie