Sunteți pe pagina 1din 48

Raducan (Vrinceanu) Lidia

Facultatea :
Stiinte si Mediu
Specializarea: Matematica-Informatica
Anul:
2

METODE DE SORTARE
SI CAUTARE

Coordonator:Asist. Bocaneala Corina

PREZENTARE GENERAL
In ultimii ani asistm la o dezvoltare n ritm accelerat a
utilizrii calculatoarelor, numrul utilizatorilor se mreste
simtitor. De aceea, prin aceast lucrare am vrut s-i ajutm

pe cei dornici de a ntelege si de a nvta cei mai importanti


algoritmi de sortare, deoarece ei constituie o disciplin
fundamental n stiinta calculatoarelor. Deci scopul acestei
lucrri este s prezinte ntr-o manier accesibil pentru
utilizatorii tehnicii de calcul cteva metode de sortare cum ar
fi: Bubblesort, Selection sort, Insertion sort, Rank sort si
Shellsort, Quicksort, Mergesort, Heapsort.

Lucrarea de fat prezint pe scurt cele mai importante


informatii despre principalele metode de sortare ncepnd de
la cele mai simple pn la cele complexe :
simple : Bubblesort, Selection sort, Insertion sort, Rank sort
si Shellsort
complexe : Quicksort, Mergesort, Heapsort, Radixsort
Metodele simple sunt ntotdeauna mai potrivite pentru
un numr de elemente mai mici dect 50. Tabelele aproape
(sau deja) sortate, sau cele care contin un numr mare de
chei egale, sunt relativ usor de sortat cu ajutorul algoritmilor
simplii. Necesit relativ putin timp de programare si
mentinere.
Metodele complexe pot sorta N elemente ntr-un timp
proportional cu NlogN. Nici un algoritm nu poate folosi mai
putin de NlogN comparatii ntre chei. Sunt eficiente mai ales
pentru sortarea unui numr mare de elemente. Necesit mai
mult timp pentru programare dar sunt mai eficiente.

CUPRINS

1. Notiuni teoretice
2. Metode de sortare
2.1. Sortarea prin metoda bulelor
2.2 . Sortarea prin metoda selectiei
2.3. Sortarea prin metoda insertiei
2.4. Sortarea prin enumerare
2.5. Shellsort
2.6. Sortarea prin interclasare
2.7. Sortarea rapida
2.8. Sortarea prin ansamblare
3. Metode de cautare
3.1. Cautare secventiala
3.2. Cautare binara
4. Concluzii
5. Bibliografie

1.NOTIUNI TEORETICE
Sortarea este o metoda (un algoritm), prin intermediul
careia se poate ordona o anumita clasa de obiecte concrete

sau abstracte, dupa unul sau mai multe criterii impuse iar
cautarea este o metoda, prin intermediul careia, se poate
cauta, dupa criterii precizate, pentru regasirea unui anumit
obiect concret sau abstract intr-o multime ordonata sau nu,
de obiecte concrete sau abstracte.
Ca exemple se pot da :
-

sortarea
(ordonarea)
crescatoare
sau
descrescatoare a unui sir de numere reale si cautarea
unui numar sau a mai multor numere in acest sir de
numere.

sortarea unei liste de persoane in ordinea


alfabetica a numelor si prenumelor acestora si
cautarea unei persoane sau a mai multor persoane cu
anumite caracteristici precizate.

ordonarea unei liste de persoane dupa importanta


muncii lor si cautarea unor persoane dupa criterii
precizate.

ordonarea unei liste de persoane dupa anumite


criterii preferentiale si cautarea in aceasta lista.

Divide et impera se bazeaz pe principiul descompunerii


problemei n dou sau mai multe subprobleme (mai uoare),
care se rezolv, iar soluia pentru problema iniial se obine
combinnd soluiile subproblemelor. De multe ori,
subproblemele sunt de acelai tip i pentru fiecare din ele se
poate aplica aceeai tactic a descompunerii n (alte)
subprobleme, pn cnd (n urma descompunerilor repetate)
se ajunge la probleme care admit rezolvare imediat.

Nu toate problemele pot fi rezolvate prin utilizarea acestei


tehnici. Se poate afirma c numrul celor rezolvabile prin
"divide et impera" este relativ mic, tocmai datorit cerinei ca
problema s admit o descompunere repetat.
Divide et impera este o tehnic ce admite o
implementare recursiv. Principiul general prin care se
elaboreaz algoritmi recursivi este: "ce se ntmpl la un
nivel, se ntmpl la orice nivel" (avnd grij s asigurm
condiiile de terminare). Aadar, un algoritm prin divide et
impera se elaboreaz astfel: la un anumit nivel avem dou
posibiliti:
1. s-a ajuns la o problem care admite o rezolvare imediat
(condiia de terminare), caz n care se rezolv i se
revine din apel;
2. nu s-a ajuns n situaia de la punctul 1, caz n care
problema curent este descompus n (dou sau mai
multe) subprobleme.

2. METODE DE SORTARE
2.1. Sortarea prin metoda bulelor (Bublle sort)
Cu toate c sortarea prin metoda bulelor reprezint
una dintre cele mai cunoscute i mai utilizate metode de
ordonare, eficiena acesteia este una foarte sczut. Astfel,
algoritmul secvenial de sortare prin metoda bulelor are o
complexitate de ordinul O(n2 ) datorit faptului c sunt
comparate perechi ce sunt interschimbate n cazul n care
criteriul de ordonare nu este ndeplinit. Dup o parcurgere
integral a elementelor vectorului, procesul se reia ncepnd
din nou cu primul element. Algoritmul mai este cunoscut sub
denumirea de metoda bulelor datorit faptului c, la fiecare
pas, elementele sunt deplasate ctre poziia corect n
funcie de condiia de sortare. Dup fiecare iteraie, o parte
dintre elementele vectorului (ncepnd de la cel de-al doilea
din ultima pereche modificat) sunt deja ordonate. Algoritmul
i ncheie execuia dup un numr de maxim n1 iteraii,
atunci cnd, la o nou parcurgere, nu s-a mai produs nici o
interschimbare. Datorit faptului c sunt comparate n ordine
perechi de elemente adiacente, algoritmul de sortare prin
metoda bulelor nu este foarte uor de paralelizat. Pentru
obinerea variantei paralele se folosete metoda numit

transpoziie par-impar. Astfel, fiecare iteraie este realizat n


dou faze. n prima dintre ele, denumit faz impar,

elementele cu indici impari sunt comparate cu vecinii din


dreapta i se efectueaz interschimbarea acestora n cazul n
care nu este ndeplinit relaia de ordine. n cea de-a doua
faz, numit faza par, elementele cu indici pari se compar
cu vecinii din dreapta, efectundu-se interschimbarea dac
este nevoie. Ordonarea vectorului este complet dup un
numr de maxim n faze (n/2 iteraii), unde n reprezint
numrul de elemente ale vectorului. Iteraiile buclelor
interioare vor fi executate simultan (n paralel) pe
procesoarele disponibile n cadrul sistemului. Complexitatea
secvenial a algoritmului de sortare prin metoda bulelor este
de ordinul O(n2 ), iar cea paralel se reduce la O(n).
Algoritmul de sortarea prin metoda bulelor va sorta
elementele din vectorul v1, v2 ,...,vn astfel nct dup sortare,
acestea vor fi n ordinea v1 v2 ... vn. Ne propunem s
facem o ordonare cresctoare a vectorului v1, v2 ,...,vn.
Algoritmul const n parcurgerea tabloului v de mai multe ori,
pn cnd devine ordonat. La fiecare pas se compar dou
elemente consecutive vi i vi+1 . Dac vi > vi+1 , (i = 1, 2, ..., n
- 1), atunci cele dou valori se interschimb ntre ele.
Controlul aciunii repetitive este dat de variabila boolean ok,
care la fiecare reluare a algoritmului primete valoarea
iniial adevrat, i care se schimb n fals dac s-a efectuat
o interschimbare de dou elemente consecutive. n
momentul n care tabloul v s-a parcurs fr s se mai
efectueze nici o schimbare, ok rmne cu valoarea iniial

adevrat i algoritmul se termin, deoarece tabloul este

ordonat.
Interschimbarea a dou elemente se realizeaz prin
intermediul variabilei auxiliare aux care are acelai tip ca i
elementele tabloului.

Algoritmul in pseudocot:
Subalgoritm Metoda_bulelor(v,n)
repet
ok < adevrat
pentru i=l,n-l execut
dac v[i]>v[i+l]atunci
ok fals
aux v[i]
v[i] v[i+1]
v[i+l] aux
sfrit dac
sfrit pentru
pn cnd ok
sfrit subalgoritm
Metoda este numit sortare cu bule pentru c elementele
mari se ridic la suprafa pn n poziia lor corect, ca nite

bule n ap. Sortarea cu bule mai este cunoscut i sub


denumirea selectare prin interschimbare sau propagare.

Algoritmul n C++ :
void Metoda_bulelor(int (&v)[20], int n)
{int ok,i,aux;
do{
ok=1;
for(i=1;i<=n-1;i++)
if(v[i]>v[i+1])
{ok=0;
aux=v[i];
v[i]=v[i+1];
v[i+1]=aux;
}
}
while(ok!=1);
}
BubbleSort nu foloseste alte structuri de date si din
aceasta cauza este recomandabil in cazurile cu putine
elemente de sortat si in cazul in care memoria este limitata.

2.2.Sortarea prin metoda selectiei


(Selection sort)

Sortarea prin metoda seleciei presupune determinarea


elementului minim dintre cele nesortate i aducerea lui pe
poziia corect. Iniial, algoritmul va determina elementul
minim din vector care va fi adus pe prima poziie, dup care
se determin minimul din vectorul rmas care va fi adus pe a
doua poziie, amd. Complexitatea secvenial a algoritmului
este tot de ordinul O(n2 ) ns performanele metodei sunt cu
60% mai bune fa de sortarea prin metoda bulelor. Indiferent
de ordinea iniial a elementelor vectorului, algoritmul va
efectua un numr de n(n-1)/2 comparaii i n-1 interschimbri
iar din acest motiv ordinul de complexitate al variantei
secveniale este egal cu O(n2 ). Paralelizarea algoritmului se
realizeaz prin distribuirea iteraiilor buclei interioare pe
procesoarele disponibile n cadrul sistemului. Datorit
faptului c iteraiile interioare vor fi executate simultan,
ordinul de complexitate al variantei paralele a algoritmului
devine O(n).
Ideea
algoritmului
este
urmatoarea:
tabloul
unidimensional este imprit in dou pri imaginare o
parte sortat i o parte nesortat. La nceput, partea sortat
este goal, n timp ce partea nesortat conine ntreg tabloul.
La fiecare pas, algoritmul gsete elementul minim din
partea nesortat i l adaug la finalul prii sortate. Cnd
partea nesortat rmne goal, algoritmul se oprete.

unidimensional,

Cnd algoritmul sorteaz un tablou


interschimb primul element al prii

nesortate cu elementul minim i dup aceea el este inclus n


partea sortat. Aceast implementare a sortrii prin selecie
nu este stabil. n cazul cnd sortm o list, i, n loc de
interschimbri, elementul minim este legat de partea
nesortat, sortarea prin selecie este stabil.
Exemplu:
Dorim s sortm irul {5, 1, 9, -2, 14, 2, 9,} utiliznd sortarea
prin selecie.
Legend:
Partea nesortat;
Partea sortat;
Elementele care vor fi interschimbate.
5, 1, 9, -2, 14, 2, 9;
5, 1, 9, -2, 14, 2, 9; interschimbm 5 cu -2
-2, 1, 9, 5, 14, 2, 9; 1 rmne pe poziie
-2, 1, 9, 5, 14, 2, 9; interschimbm 2 cu 9
-2, 1, 2, 5, 14, 9, 9; 5 ramne pe poziie
-2, 1, 2, 5, 14, 9, 9; interschimbm 14 cu 9
-2, 1, 2, 5, 9, 9 14; vector sortat

Algoritmul in pseudocod:
pentru i 0,n-1 execut

nesortat

min i ;
pentru j i+1,n execut
dac v[j]<v[i] atunci
min j ;
sfdac
sfpentru
dac min i atunci
aux v[i] ;
v[i] v[min] ;
v[min] aux ;
sfdac
sfpentru

Algoritmul in c++:
#include <iostream>
using namespace std;
int main (){
int n, a[100], i, j, k, man, min;
//se citesc datele de intrare
cout<<"n=";cin>>n;
for (i=0;i<n;i++){
cout<<"a["<<i<<"]="; cin>>a[i];

}
// se sorteaza vectorul
for (i=0;i<n-1;i++){
min=a[i];
k=i;
for (j=i+1;j<n;j++)
if (a[j]<min){
min=a[j];
k=j;
}
man=a[k];
a[k]=a[i];
a[i]=man;
}
//se afiseaza rezultatele
for (i=0;i<n;i++)
cout<<a[i]<<" ";
return 0; }

2.3.Sortarea prin insertie (Insertion sort)

Aa cum i spune i numele, sortarea prin metoda


inseriei nu face altceva dect s insereze fiecare element al
vectorului n poziia n care valoarea acestuia se ncadreaz
conform criteriului de ordonare. Cea mai simpl
implementare a algoritmului necesit existena a dou liste
vectorul iniial i cel n care sunt scrise elementele ordonate
conform criteriului de sortare. Pentru a economisi memorie,
cele mai multe implementri, dup ce au inserat un element,
gliseaz toate valorile ce urmeaz cu o poziie la dreapta. Se
reduce astfel numrul de interschimbri deoarece dac un
element este mai mare ca precedentul, atunci acesta se
consider a fi deja ordonat. Dei ordinul de complexitate al
variantei secveniale a algoritmului este tot O(n2 ), sortarea
prin inserie este de peste 2 ori mai eficient dect algoritmul
de sortare prin metoda bulelor. Pentru obinerea variantei
paralele a algoritmului, bucla interioar va fi modificat astfel
nct s realizeze doar calculul poziiei la care trebuie s se
fac inserarea, fr deplasarea corespunztoare a
elementelor vectorului. Aceast din urm operaie va aprea
individualizat n cadrul unei noi bucle interioare care va fi
executat n paralel. Datorit faptului c mai multe
procesoare vor dori s modifice simultan valorile variabilei
care reine poziia la care se va efectua inserarea elementului
curent i a celei ce semnalizeaz faptul c poziia la care se
va insera elementul curent a fost deja calculat, actualizarea
acestora trebuie inclus n cadrul unor seciuni critice care
realizeaz serializarea cererilor de acces concurent cu
ajutorului mecanismului de excludere mutual. Ordinul de
complexitate al algoritmului paralel de sortare prin metoda

inseriei este egal cu O(n), net superior fa de cel al celui


mai rapid algoritm de sortare secvenial care este O(n log n).

Sortarea prin inserare seaman oarecum cu sortarea prin


selecie. Tabloul este mprit imaginar n dou pari - o parte
sortat i o parte nesortat. La nceput, partea sortat
conine primul element al tabloului i partea nesortat
conine restul tabloului. La fiecare pas, algoritmul ia primul
element din partea nesortat i l insereaz n locul potrivit al
prii sortate. Cnd partea nesortat nu mai are nici un
element, algoritmul se oprete.
Exemplu:
S sortm irul {9, -5, 2, 12, 4} folosind sortarea prin inserie.
9, -5, 2, 12, 4

nesortat

9, -5, 2, 12, 4

-5 va fi inserat 9 > -5 , interschimbm

-5, 9, 2, 12, 4

2 va fi inserat 9 > 2, interschimbm

-5, 2, 9, 12, 4

-5 < 2 , 2 nu se face interschimbare

-5, 2, 9, 12, 4
interschimbare

12 va fi inserat 9 < 12 nu se face

-5, 2, 9, 12, 4

4 va fi inserat, 4 < 12, interschimbm

-5, 2, 9, 4, 12

4 < 9 , interschimbm

-5, 2, 4, 9, 12

sortat

Algoritmul in pseudocod:

pentru i 1,n execut


j i ;
ct timp j>0 si v[j-1]>v[j] execut
aux v[j] ;
v[j] v[j-1] ;
v[j-1] aux ;
j j-1 ;
sfct timp
sfpentru
Sortarea prin inserare este un algoritm simplu de sortare
prin compararea unor elemente aflate n tablouri de date
sortate, construind cte o intrare la un anumit timp.
Acest tip de algoritm este mai puin eficient n lucrul cu liste
mari de date, i nu are performana algoritmilor de sortare
avansai cum sunt algoritmul de sortare rapid quick sort
sau merge sort.

Algoritmul in c++:

#include <iostream.h>
int main()
{

int v[100],n,i,j,aux;
cout<<"n= ";cin>>n;
cout<<"v[1]= ";cin>>v[1];
for(i=2;i<=n;i++)
{
cout<<"v["<<i<<"]= ";
cin>>v[i];
j=i;
while(v[j]<v[j-1] && j>1)
{
aux=v[j];
v[j]=v[j-1];
v[j-1]=aux;
j--;
}
}
cout<<"Vectorul sortat este: ";
for(i=1;i<=n;i++)
cout<<v[i]<<" ";
return 0;}

Aceasta metoda aseaza elementul citit pe pozitia


lui finala in vector, comparandul cu valorile introduse deja si
interschimbandul pana ajunge in pozitia corecta.

2.4.Sortarea prin enumerare (Rank sort)


Algoritmul de sortare Rank Sort, cunoscut i sub
denumirea de sortare prin enumerare, are la baza ideea de a
determina rangul fiecrui element al vectorului, rang care va
fi apoi utilizat pentru punerea elementului pe poziia corect.
Prin rangul unui element vom nelege numrul total de
elemente din list care sunt mai mici dect elementul
respectiv. Pentru a calcula rangul unui element este necesar
ca acesta s fie comparat cu fiecare element al listei. n cazul
unei liste ordonate ascendent, rangul unui element va fi de
fapt pozi- ia sa actual. Dac lista nu este deja ordonat,
rangul elementelor ne va indica poziia final a acestora n
lista sortat. Metoda de sortare prin enumerare calculeaz
rangul fiec- rui element din list dup care folosete aceste
valori pentru a plasa elementele n poziia corect. Indiferent
de relaia de ordine existent iniial ntre elementele
vectorului, algoritmul secvenial va efectua un numr de n 2
iteraii i comparaii, datorit existenei a dou bucle
imbricate, fiecare dintre ele avnd un numr de n iteraii. Din
acest motiv putem afirma faptul c ordinul de complexitate al
algoritmului secvenial este egal cu O(n2 ). Paralelizarea
algoritmului se poate realiza prin execuia concurent, pe
procesoarele disponibile n sistem, a iteraiilor buclei

exterioare. n felul acesta rangul unui element va fi calculat n


mod independent pe unul dintre procesoarele sistemului
paralel. Datorit faptului c iteraiile buclei exterioare sunt
executate n paralel (complexitate egal cu O(1)), ordinul de
complexitate al algoritmului paralel de sortare prin
enumerare va fi egal cu O(n). Acest rezultat, care este net
superior n comparaie cu performanele celui mai rapid
algoritm secvenial de sortare, se obine indiferent de modul
n care sunt dispuse iniial elementele vectorului. Dei face
parte din categoria algoritmilor de sortare cu complexitate de
ordinul O(n2 ), Rank Sort este un algoritm foarte simplu care
poate fi folosit cu succes pentru ordonarea unor seturi de
date de dimensiune moderat.
Metoda sortrii prin numrare const n gsirea pentru
fiecare element A[i], a numrului de elemente din vector, mai
mici ca el. Numerele obinute sunt memorate ntr-un vector
C; elementele vectorului de sortat A, sunt iniial atribuite
vectorului B. Pe baza vectorului C, elementele lui B vor fi
aranjate n vectorul A.
Exemplu:
Vrem s sortm urmatorul ir:
A= (9, -5, 2, 12, 4)
Elementele lui A le atribuim lui B:
B= (9, -5, 2, 12, 4)
Pentru fiecare element A[j] numrm cte elemente sunt
mai mici ca el, aceste numere reinndu-le n vectorul C:

C=(3, 0, 1, 4, 2) se reconstitue
A[c[1]+1]=B[1];A[c[2]+1]=B[2]...

vect

astfel:

obinndu-se vectorul A sortat (-5, 2, 4, 9, 12)


16

Algoritmul n pseudocod
Pentru i 1,n execut
b[i] a[i];
sfpentru
pentru j 2,n execut
pentru i 1,j-1 execut
dac a[i]<a[j] atunci
c[j] c[j]+1
altfel c[i] c[i]+1;
sfdac
sfpentru
sfpentru
pentru i 1,n execut
a[c[i]+1] b[i]
sfpentru
Se citesc de la tastatura n numere. Ordonati crescator
numerele, folosind metoda numararii.

#include<iostream.h>
int
{int
cout<<n=;cin>>n;
for(i=1;i<=n;i++)
17
{cout<<a["<<i<<"]=;
cin>>a[i];
}
for(i=1;i<=n;i++)
{b[i]=0;
for(j=1;j<=n;j++)
if(a[j]<a[i])
b[i]++;
}
for(i=1;i<=n;i++)
c[b[i]+1]=a[i];
for(i=1;i<=n;i++)
cout<<c[i]<<
}

main()
a[100],b[100],c[100],n,i,j;

2.5.Shell sort
Shell Sort Creat de Donald Shell n anul 1959, Shell Sort
reprezint unul dintre cei mai vechi algoritmi de sortare.
Cunoscut i sub numele de Comb Sort, este cel mai complex
i cel mai eficient algoritm din clasa celor de ordinul O(n2 ).
Dei este un algoritm rapid, uor de neles i de interpretat,
analiza complexitii acestuia este o sarcin foarte
complicat deoarece se poate deduce n mod intuitiv modul

n care algoritmul funcioneaz ns analiza formal a


timpului de execuie este o problem nc nerezolvat
Algoritmul shell sort este o generalizare a
algoritmului insertion sort. La algoritmul insertion sort,
pentru a insera un nou element n lista de elemente deja
sortate, se deplaseaz fiecare element cu cte o poziie spre
dreapta att timp ct avem elemente mai mari dect el.
Practic fiecare element nainteaz spre poziia sa final cu
cte o poziie.
Algoritmul shell sort lucreaz similar, doar c deplaseaz
elementele spre poziia final cu mai mult de o poziie. Se
lucreaz n iteraii. n prima iteraie se aplic un insertion sort
cu salt s1 mai mare dect 1. Asta nseamn c fiecare
element din irul iniial este deplasat spre stnga cu
cte s1 poziii att timp ct ntlnete elemente mai mari
dect el.
n a doua iteraie se aplic un insertion sort cu un salt s2,
mai mic dect s1 i mai mare dect 1. Din nou fiecare
element din ir este deplasat spre stnga cu cte s2 poziii,
att timp ct ntlnete elemente mai mari dect el.
Se repet asemenea iteraii cu salturi din ce n ce mai
mici, s3, s4, etc. Ultima iteraie se face cu saltul 1. Aceast
ultim iteraie este practic un insetion sort clasic.
Principiul este c dup fiecare iteraie irul devine din ce n
ce mai sortat. Iar cum algoritmul insertion
sort funcioneaz cu att mai repede cu ct irul este mai
sortat, per ansamblu vom obine o mbuntire de vitez.
Exemplu:
Fie irul:

32 95 16 82 24 66 35 19 75 54 40 43 93 68
Prima iteraie se face cu salt 5. Evident c pentru a putea
face deplasri spre stnga cu cte 5 poziii vom porni de la
elementul al 6-lea din ir, adic 66. ncercm s l deplasm
pe 66 cu 5 poziii spre stnga, dar vedem c acolo este 32, un
numr mai mic. Trecem la 35. ncercm s l deplasm cu 5
poziii spre stnga i vedem c acolo se afl 95, un numr
mai mare. Ca urmare facem efectiv deplasarea, iar 95 trece n
locul lui 35. Obinem:
32 35 16 82 24 66 95 19 75 54 50 43 93 68
Trecem la 19, acesta ar trebui deplasat n locul lui 16 care e
mai mic, deci nu facem nimic. Trecem la 75. Acesta se va
deplasa n locul lui 82, iar 82 vine n locul lui 75. Obinem:
32 35 16 75 24 66 95 19 82 54 50 43 93 68
Trecem la 54. Acesta ar trebui deplasat n locul lui 24, care e
mai mic, deci nu facem nimic. Trecem la 50. Acesta se
deplaseaz n locul lui 66, iar 66 vine n locul lui 50. Pe 50 lam mai putea deplasa o data, dar ar trebui s ia locul lui 32
care este mai mic, deci ne oprim. Obinem:
32 35 16 75 24 50 95 19 82 54 66 43 93 68
Urmeaz 43, care se deplaseaz n locul lui 95, iar 95 vine n
locul lui 43. Pe urm pe 43 l-am mai putea deplasa n locul lui
35, dar acesta e mai mic, deci nu facem deplasarea. Obinem:
32 35 16 75 24 50 43 19 82 54 66 95 93 68

Trecem la 93, acesta e mai mare dect 19, deci nu se


deplaseaz nicieri.
Trecem la 68. Acesta e mai mic dect 82, deci se deplaseaz
n locul lui, iar 82 vine n locul lui 68. Pe urm vedem c 68 e
mai mic dect 75, deci l deplasm din nou, iar 75 vine n
locul lui 68. Obinem:
32 35 16 68 24 50 43 19 75 54 66 95 93 82
Cu asta se ncheie prima iteraie, de salt 5. Putem observa c
deja irul este mai sortat dect a fost iniial. Se poate
continua cu o iteraie de salt 3 i pe urm cu una de salt 1, n
urma cruia irul va fi deplin sortat.
irul salturilor pentru iteraii se poate alege n diverse
moduri. O variant este s se porneasc de la N/2 i de la o
iteraie la alta s se njumteasc saltul, pn cnd se
ajunge la 1. O alt variant este s se foloseasc iruri
predefinite. Spre exemplu irul (701, 301, 132, 57, 23, 10, 4, 1)
se consider c este foarte bun n ceea ce privete numrul
de comparaii efectuate.

Algoritmul shell sort n pseudocod este:


/* Aici se poate folosi orice ir de salturi. Atentie s
actualizai i numarul de iteraii in mod corespunztor. */
int salt[5] := {1, 4, 10, 23, 57};
int numar_iteratii := 5;
pentru iter := numar_iteratii-1 pana la 0
pentru i := salt pana la N-1
aux := a[i];

j := i salt[iter];
cat timp (j>=0) si (a[j] > aux)
a[j + salt[iter]] := a[j];
j := j salt[iter];
sfarsit cat timp;
a[j + salt[iter]] := aux;
sfarsit pentru;
sfarsit pentru;

Insertion Sort este un algoritm foarte eficient n


condiiile n care datele de intrare sunt aproape sortate ns,
per ansamblu, eficiena acestuia scade datorit faptului c
elementele sunt deplasate doar cu cte o poziie. Shell Sort
este un algoritm foarte similar cu Insertion Sort dar care
folosete pai mai mari ca unitatea pentru rearanjarea
valorilor vectorului. Dimensiunea pasului scade de la o
iteraie la alta astfel nct n final algoritmul va efectua o
sortare clasic prin inserie dar aplicat asupra unor valori ce
sunt aproape ordonate. Astfel, dac o valoare mic este
poziionat ctre sfritul vectorului, algoritmul de sortare
prin inserie va avea nevoie de aproximativ n comparaii i
interschimbri pentru a muta elementul respectiv pe poziia
corect. Folosind ns Shell Sort, datorit faptului c
algoritmul folosete pai de dimensiune mai mare, valoarea
respectiv va fi adus pe poziia corespunztoare ntr-un
numr mult mai mic de pai. Corectitudinea algoritmului este
garantat de faptul c la ultimul pas se realizeaz o sortare
clasic a ntregului vector prin metoda inseriei. Dar datorit

faptului c datele sunt deja parial ordonate, sortarea prin


metoda inseriei va avea nevoie de doar cteva iteraii pentru
a finaliza ordonarea elementelor vectorului. Numrul acestor
iteraii depinde de modul n care se aleg dimensiunile pailor
de calcul. Dimensiunea seturilor de date folosite la fiecare
pas al algoritmului are un impact major asupra eficienei cu
care se realizeaz operaia de ordonare. n cazul cel mai
defavorabil, algoritmul necesit O(n2 ) comparaii i
interschimbri. Pentru obinerea varintei paralele vor trebui
parcurse aceleai etape ca i n cazul sortrii prin inserie,
obinndu-se un algoritm ce are ordinul de complexitate egal
cu O(n). Algoritmul Shell Sort este de departe cel mai rapid
algoritm din clasa celor de complexitate secvenial egal cu
O(n2 ). Astfel, viteza algoritmului este de aproximativ cinci ori
mai mare fa de sortarea prin metoda bulelor i de peste
dou ori mai mare n comparaie cu metoda de sortare prin
inserie. Cu toate c algoritmul este mai lent n comparaie cu
alte metode de sortare (cum ar fi, de exemplu, Quick Sort,
Merge Sort sau Heap Sort), simplitatea acestuia l face s fie
o foarte bun alegere pentru cazurile n care se dorete
sortarea repetat a unor liste de dimensiune moderat.

2.6.Sortarea prin interclasare (Merge sort)


Sortarea prin metoda Merge Sort are la baz
algoritmul de interclasare ce divizeaz lista de sortat n dou
subliste care sunt apoi recursiv ordonate dup care se

23
execut o operaie de interclasare pentru obinerea listei
finale. Implementrile clasice folosesc trei vectori, doi pentru
subliste i unul pentru obinerea rezultatului final ns
algoritmul poate fi modificat astfel nct s lucreze cu doar
dou masive: unul pentru datele de intrare i unul n care se
vor memora elementele ordonate. Complexitatea algoritmului
secvenial este egal cu O(n log n). Paralelizarea algoritmului
se va face prin distribuirea apelurilor ctre procesoarele
sistemului. n felul acesta, fiecare procesor va opera asupra
unuia sau a mai multor subvectori obinui pe baza vectorului
iniial. Datorit distribuirii apelurilor recursive, ordinul de
complexitate al variantei paralele a algoritmului este egal cu
O(n). Acest ordin de complexitate este net superior fa de
cel al celui mai rapid algoritm secvenial de sortare. Dei
sortarea prin interclasare este un algoritm stabil ce necesit
cu 30% mai puine comparaii dect Quick Sort, metoda este
mai lent dect Quick Sort datorit faptului c efectueaz mai
multe interschimbri.
Algoritmul de sortare prin interclasare se bazeaz pe
urmtoarea idee: pentru a sorta un vector cu n elemente l
mpim n doi vectori care, odat sortai, se interclaseaz.
Conform strategiei Divide et Impera, problema este
descompus n alte dou subprobleme de acelai tip i, dup
rezolvarea lor, rezultatele se combin (n particular se
interclaseaz). Descompunerea unui vector n ali doi vectori
care urmeaz a fi sortai are loc pn cnd avem de sortat
vectori de una sau dou componente
Exemplu
Sortarea unui ir de apte valori de tip ntreg.

38

38

38

27

27

27

43

43

43

82

82

10

82

Divizare

10

10

Sort(p,q,A);
Sortare
27
38
3
43 ct timp
9
82 i<=m10execut
dac A[p]>A[q] atunci
kk+1 B[k] A[i] ii+1
interschimba A[p]A[q]
sfct timp
sfSort
3
27
38
43
9
10
82
ct timp j<=q execut
Interc(p,q,m,A)
Interclasare
kk+1 B[k] A[j];jj+1
ip;jm+1;k0;
sfct timp
27
43
3
9
10 execut
38
82
ct timp i<=m si
j<=q
pentru ip,q execut
dac A[i]<A[j]
Algoritmulatunci
in pesudocod
A[i] B[i]
kk+1;B[k] A[i];ii+1
Sfpentru
altfel
Divimp(p,q,A)
kk+1;B[k] A[j];jj+1;
dac q-p<=1 atunci Sort(p,q,A)
sfdac
altfel Divimp(p,m,A) Divimp(m+1,q,A
sfct timp
Interc(p,q,m,A)
sfdac
sfDivimp

Utilizand metoda divide et impera, sa se sorteze prin


interclasare un sir
#include<iostream.h>
int a[20],n;
void mergesort(int i,int m,int j)
{int b[20],x=i,k=1,y=m+1;
while(x<=m && y<=j)
if (a[x]<a[y])
b[k++]=a[x++];
else
b[k++]=a[y++];

while (x<=m)
b[k++]=a[x++];
while (y<=j)
b[k++]=a[y++];
int t=i;
for (k=1;k<=(j-i)+1;k++)
a[t++]=b[k];
}
void divimp(int i,int j)
{if (i<j)
{int m=(i+j)/2;
divimp(i,m);
divimp(m+1,j);
mergesort(i,m,j);}
}
void main()
{
cout<<"n=";
cin>>n;
for(int i=1;i<=n;i++)
{cout<<"a["<<i<<"]=";
cin>>a[i];
}
divimp(1,n);
cout<<"vectorul sortat este: "<<endl;
for(i=1;i<=n;i++)
cout<<a[i]<<' ';
}

2.7. Sortarea rapida (Quicksort)


Datorit performanelor sale deosebite, algoritmul
Quick Sort este unul dintre cei mai utilizai algoritmi de
sortare. Quick Sort este un algoritm ce poate fi descris foarte
simplu la modul teoretic ns scrierea acestuia sub forma de
cod surs a pus ntotdeauna probleme. Cercettorii din
domeniul informaticii au avut nevoie de ani de zile pentru a
obine o implementare practic a acestui algoritm. Quick Sort
este cel mai cunoscut algoritm de sortare din clasa celor de
complexitate medie O(n log n). Algoritmii din aceast clas
nu sunt la fel de intuitivi ns sunt mult mai performani dect
cei de complexitate O(n2 ). Aa cum se poate observa cu
uurin, Quick Sort reprezint o variant mai rapid a
algoritmului Merge Sort.
Varianta recursiv a algoritmului se compune din
patru pai care vor fi descrii n continuare:
1. Dac toate elementele vectorului au fost deja ordonate
atunci execuia algoritmului se ncheie imediat.

2. Se alege unul din elementele vectorului pe post de pivot.


3. Se mparte vectorul n doi subvectori (dou partiii) care
vor conine doar elemente mai mici, respectiv mai mari dect
pivotul .
4. Algoritmul se repet recursiv pentru ambele partiii
obinute anterior.

Cu toate c este un algoritm de sortare foarte rapid,


utilizarea Quick Sort poate conduce la umplerea stivei atunci
cnd se utilizeaz seturi largi de date. n plus, datorit
complexitii, algoritmul nu este o alegere practic atunci
cnd se dorete ordonarea unor seturi de date de
dimensiune redus. Modul n care este ales elementul care
joac rol de pivot are un impact major asupra performanelor
algoritmului. n cazul cel mai defavorabil, ordinul de
complexitate al algoritmului este egal cu O(n2 ) i se obine
n situa- ia n care elementele vectorului sunt deja ordonate
iar pe post de pivot se alege elementul cel mai din stnga.
Paralelizarea algoritmului se face prin distribuirea
apelurilor succesive ctre procesoare diferite ale sistemului.
n felul acesta, fiecare procesor va opera asupra uneia sau a
mai multor partiii obinute pe baza vectorului iniial. n plus,
cele dou bucle repetitive din cadrul procedurii de
partiionare care determin indicii elementelor din subvectori
care nu respect relaia de ordine pot fi executate n paralel
iar corectitudinea rezultatelor obinute este garantat de
existena unui punct de sincronizare. Ordinul de
complexitate al variantei paralele a algoritmului este dat de
complexitatea procedurii de partiionare care este egal cu
O(n). Acest ordin de complexitate este net superior fa de

O(n log n). Quick Sort reprezint unul dintre cei mai rapizi
algoritmi de sortare. Datorit acestui lucru, algoritmul
reprezint cea mai bun alegere n toate situaiile n care
viteza este un factor foarte important, indiferent de
dimensiunea seturilor de date ce se doresc a fi sortate. Cu
toate acestea nu trebuie scpat din vedere faptul c
algoritmul nu este stabil iar performanele acestuia sunt

modeste atunci cnd opereaz asupra unor liste aproape


ordonate.

Algoritmul n pseudocod:
quickSort(V,st,dr);
pivotv[(st+dr) div 2)];
ct timp i<=j execut
ct timp v[i] <pivot execut
ii+1;
dac i<=j atunci
auxv[i];
v[i]v[j];
v[j]aux;
ii+1;
jj-1;
dac st<j atunci

quikSort(v,st,j);
dac i<dr atunci
quikSort(v,i,dr);

Exemplu:
Fie vectorul de sortat 7, 8, 2, 9, 3.
v=7; i=1 ; j=5; 3<=7; deci
se interschimb; i=2; j=4;
8>=7 atunci 9<=7 (nu); j=3; 2<=7
(da); le interschimb;i=3; j=2;

j
38297
i j
32

897
8>=7 atunci 2<=7(da); i>=j STOP
RETURNEAZ j=2
a)
v=3; i=1; j=2; 2<=3(da); se
interschimb; i=2; j=1; STOP;
b)
v=8; i=3; j=5; 7<=8(da); se
interschimb; i=4; j=4;
9>=8(da);
9<=8(nu); j=3; 7<=8(da);i>=j STOP R
ETURNEAZ j=3

2 subvectori: 3 2
897
2 3

7 9 8
2 3
7

a)
v=9; i=4; j=5; 8<=9(da); se
interschimb; i=5; j=4;
9>=9(da); 8<=9(da); i>=j STOP
VECTORUL SORTAT:

8 9
2 3 7 8 9

Sa se ordoneze crescator un vector v, folosind metoda de


sortare rapida (quick sort).

#include<iostream.h>
int v[100],n,k;
void poz(int li,int ls,int & k,int v[100])
{
int i=li,j=ls,c,i1=0,j1=-1;
while(i<j)
{
if(v[i]>v[j])
{
c=v[j];v[j]=v[i];v[i]=c;
c=i1;i1=-j1;j1=-c;
}
i=i+i1;
j=j+j1;
}
k=i;
}
void quick(int li,int ls)
{
if(li<ls)

{
poz(li,ls,k,v);
quick(li,k-1);

quick(k+1,ls);
}
}
void main()
{
int i;
cout<<"n=";cin>>n;
for(i=1;i<=n;i++)
{
cout<<"v["<<i<<"]=";
cin>>v[i];
}
quick(1,n);
for(i=1;i<=n;i++) cout<<v[i]<<" ";
}
Quick Sort este unul dintre cei mai rapizi i mai
utilizai algoritmi de sortare pn n acest moment,
bazndu-se pe tehnica "Divide et Impera".

2.8. Sortarea prin asamblare (Heapsort)


Se numete ansamblu (heap) a secven de chei h1,
h2,..., hn care satisfac condiiile: hi <= h2i si hi <= h2i+1
i=1,N/2.
Se aduce tabloul la forma unui ansamblu, adic pentru orice
i,j, k din intervalul [1,N], unde j=2*i si k=2*i+1, s avem
a[i]<=a[j] si a[i]<=a[k] (*). Se observ c n acest caz a[1] este
elementul cu cheia minim n tablou. Se interschimb

elementele a[1] i a[N] i se aduce subtabloul a[1],...,a[N-1] la


forma de ansamblu, apoi se interschimb elementele a[1] si
a[N-1] i se aduce subtabloul a[1],...,a[N-2] la forma de
ansamblu .a.m.d. n final rezult tabloul ordonat invers.
Dac se schimb sensul relaiilor n condiiile (*) atunci se
obine o ordonare direct a tabloului (a[1] va fi elementul cu
cheia maxim).
Aducerea unui tablou la forma de ansamblu se bazeaz pe
faptul c subtabloul a[N/2+1],...,a[N] este deja un ansamblu
(nu exist indicii j si k definii ca mai sus). Acest subtablou
se va extinde mereu spre stnga cu cte un element al
tabloului, pna cnd se ajunge la a[1]. Elementul adugat va
fi glisat astfel nct subtabloul extins s devin ansamblu.
Procedura Deplasare(s,d) realizeaz glisarea elementului a[s]
astfel c subtabloul a[s],...,a[d] (s<d) s devin ansamblu.
Aceast procedur este folosit mai nti pentru aducerea
ntregului tablou la structura de ansamblu i apoi pentru
ordonarea tabloului conform metodei enunate mai sus.
Timpul de execuie al sortrii este O(N*log N).

Algoritmul n pseudocod
h1
ct timp h<n execut
hh*3 + 1;
sfct timp
ct timp h1execut

h[h / 3]
pentru ih,n xecut

xv[i] ji

ct timp v[j-h]>x execut


v[j]v[j-h]

jj-h

sfct timp
v[j]x
sfpentru
sfct timp
Exemplu:
Fie un ir cu 15 elemente. Pentru urmtoarele valori ale
pasului: h=13, h=4, h=1 (care corespund unui ir h k dat prin
relaia hk =3hk-1 +1, h1 =1):
Etapa 1: pentru h=13 se aplic algoritmul sortrii prin
inserie subirurilor x[1], x[14] i x[2], x[15], singurele
subiruri cu elemente aflate la distana h care au mai mult
de un element:
Tabloul: 14 8 10 7 9 12 5 15 2 13 6
1
4 3 11
Indici: 1
2 3
4 5 6 7 8
9 10 11 12
13 14 15
i se obine:
Tabloul: 3
4 14 11

10

12

15

13

Indici:
1 2 3
4 5 6 7 8
9 10 11 12
13 14 15
Etapa 2: pentru h=4 se aplic algoritmul sortrii prin inserie
succesiv
subirurilor:
x[1],
x[5],
x[9],
x[13],
x[2],x[6],x[10],x[14],x[3],x[7],x[11],x[15],x[4],x[8],x[12].

Dup prima subetap (prelucrarea primului subir) prin care se


ordoneaz subirul constituit din elementele marcate:
Tabloul: 3 8 10 7 9 12 5 15 2 13 6
1
4
14 11
se obine:
Tabloul: 2
14 11

10

7 3 12 5 15

4 13

La a doua subetap se aplic sortarea prin inserie asupra


subirului constituit din elementele marcate
Tabloul: 2 8
10 7 3 12 5 15
4 13 6
1
9
14 11
obinndu-se aceeai configuraie (subirul este deja ordonat
cresctor) din care se prelucreaz acum subirul constituit
din elementele marcate:
Tabloul: 2
14 11

10

12

5 15

13

Obtinandu-se:
Tabloul: 2
14 11

12 6 15

13 10

Se aplic acum sortarea prin inserie asupra subirului


constituit din elementele marcate:
Tabloul: 2 8 5 7 3 12 6 15 4 13 10 1 9
14 11
obinndu-se:
Tabloul: 2 8 5 1
3 12 6 7 4
13 10 15 9
14 11
Se aplic acum sortarea prin inserie asupra ntregului ir.

3. METODE DE CAUTARE

3.1. Cutare secvenial


Descriere
S presupunem c dorim s determinm dac un
element aparine sau nu unui vector de elemente. Dac nu
tim nimic despre elementele vectorului avem soluia cutrii
secveniale, pn gsim elementul cutat sau pn testm
toate elementele.

Algoritm descris n pseudocod


gsit 0
pentru i 0,n-1 execut
dac x=v[i] atunci
gsit 1
sfrit dac
sfrit pentru

//

Cautarea

#include<iostream.h>
#include<conio.h>
int
{int
cout<<"n=
for(i=1;i<=n;i++)

secventiala

unui

numar

main()
x[100],n,a,i,gasit=0;
";cin>>n;

{cout<<"x["<<i<<"]=
";cin>>x[i];}
cout<<endl<<"a=
";cin>>a;
for(i=1;i<=n;i++)
{if(a==x[i])
gasit=1;}
if(gasit==1)
cout<<"Numarul
"<<a<<"
se
gaseste
in
sir.";
else
cout<<"Numarul "<<a<<" nu se gaseste in sir.";
getche();
}

3.2. Cutare binar


Descriere
Dac elementele vectorului sunt ordonate cresctor,
putem s ne dm seama dac elementul nu exist n vector
fr a fi nevoie s parcurgem toate elementele vectorului.
Unul dintre algoritmii folo, sau pn cnd nu se mai poate
face mparirea n subvectori, ceea ce nseamn c nu s-a
gsit elementul.
Exemplu:
Dorim s cutm elementul x=19 ntr sii n acest caz este
algoritmul de cutare binar. Acest algoritm are la baz
principiul njumtirii repetate a domeniului n care se caut
elementul, prin mprirea vectorului n doi subvectori. Notm
cu st primul indice al vectorului i cu dr ultimul indice al
vectorului, iar m este indicele elementului din mijloc al

vectorului m=(st+dr)/2. Se compar valoarea cutat cu


valoarea elementului din mijloc. Dac cele dou valori sunt
egale nseamn c s-a gsit elementul. Dac nu sunt egale
vectorul v-a fi mprit n doi subvectori. Operaia de cutare
const n identificarea subvectorului n care se poate gsi
elementul, prin compararea valorii cutate cu cea din mijloc,
dup care se divizeaz acest subvector n doi subvectori
.a.m.d. pn cnd se gsete elementul
-un vector cu 9 elemente:

5 8 1
1

1
5

1
7

1
9

2
0

2
3

2
6

2 3

st=1 dr=9 m=5


elementul cutat este x=19
se caut n subvectorul din dreapta st=m+1=6

1 2 2 2
9 0 3 6
6

7 8 9

19<20 se caut n subvectorul din stnga dr=m-1=6

1 1
7 9

st=m=5

5 6
19>17 se 1
st=m+1=6
9
6

caut

subvectorul

Funcia CautBin(n,A,x)
p1 qn
ct timp pq execut
m [(p+q)/2]
dac x=A[m] atunci
CautBin m

p q+1

altfel
dac x<A[m] atunci q m-1
altfel p m+1

sfdac
sfct timp
sfCautBin

dreapta

st=dr=m=6 Elementul a fost gsit

Algoritm descris n pseudocod:

sdac

din

Se citete un vector cu n componente numere ntregi


(numerele se presupun ordonate cresctor) i o valoare
ntreag ("nr"). S se decid dac nr se gsete sau nu
printre numerele citite, iar n caz afirmativ s se tipreasc
indicele componentei care conine aceast valoare.
#include <iostream>
using namespace std;
int v[100], n, nr;
void caut(int i, int j)
{
int m = (i+j)/2;
if (nr==v[m])
cout<<"gasit, indice="<<m;
else
if (i<j)
if (nr<v[m])
caut(i, m-1);
else caut(m+1, j);
else cout<<"nu a fost gasit.";
}
int main( )
{
cout<<"n="; cin>>n;
for (int i=1; i<=n; i++)
{
cout<<"v["<<i<<"]="; cin>>v[i];
}
cout<<"nr="; cin>>nr;
caut (0,n);
return 0;

CONCLUZII

n lucrarea de fa am fcut o prezentare a algoritmilor


de sortare i am parcurs conceptele teoretice din spatele
acestor algoritmi.
Aplicatii ale sortrii:
n cutare: o cutare binar se execut n O(logN) timp
dac cheile sunt sortate
Perechi apropiate: fiind dat un set de N numere, cum
gsim perechea de numere care au cea mai mic
diferent dintre ele. Dup sortare sunt unul lng altul si
atunci problema este rezolvat n O(NlogN) timp
incluznd si sortarea.
Unicitatea elementelor: ca s aflm dac sunt elemente
dublicate n sirul de N elemente, sortm sirul si este mai
usor de aflat
Frecventa distributiei
Selectarea : ca s aflm care este a k-a cel mai mare
element din sir, nti sortm sirul si atunci elementul va
fi pe pozitia k
"Convex hulls": avem N pointeri n dou dimensiuni,
care este poligonul celui mai micisuprafete care contine
pe toti.

BIBLIOGRAFIE
.Doina Logofatu -Algoritmi fundamentali in C++
.Octavian Patrascoiu Elemente de grafuri si combinatorica