Sunteți pe pagina 1din 13

Sortarea prin interclasare (merge sort)

Aceasta metoda de ordonare are la baza interclasarea a doi


vectori: fiind dati doi vectori ordonati se obtine un al treilea vector
ordonat care va contine elementele din cei doi vectori.

In cazul sortarii prin interclasare vectorii care se interclaseaza


sunt doua secvente ordonate din acelasi vector

Sortarea prin interclasare utilizeaza metoda Divide et Impera:

-se imparte vectorul in secvente din ce in ce mai mici., astfel incat


fiecare secventa sa fie ordonata la un moment dat si interclasata
cu o alta secventa din vector corespunzatoare.
-practic interclasarea va incepe cand se ajunge la o secventa
formata din doua elemente. Aceasta odata ordonata se va
interclasa cu o alta corespunzatoare. Cele doua secvente vor
alcatui in subsir ordonat din vector mai mare care la randul lui se
va interclasa cu subsirul corespunzator samd.

Fie vectorul:

8 7 9 3 6 4 17 16

Se imparte in doua secvente:

8 7 9 3 6 4 17 16

In continuare pt prima secvente se procedeaza la fel:

8 7 9 3

Dupa o noua impartire se obtine:

8 7

Se incepe interclasarea. Se considera ca avem doi vectori de


lungime 1 care se interclaseaza:

8 7
Rezulta:

1
7 8

La fel si pentru secventa :

9 3 Se considera ca avem iar doi vectori de


lungime 1 care se interclaseaza:

9 3

Rezulta:

3 9

Ceea ce inseamna ca cele doua secvente determina obtinerea


urmatorului subsir din vector:

7 8 3 9

Pentru care se interclaseaza cele doua zone. Rezulta:

3 7 8 9

La fel se procedeaza si cu secventa:

6 4 17 16

Se obtine:
6 4
Care se interclaseaza si se obtine:

4 6

La fel pentru:
17 16

Se obtine:
16 17

Se obtine o noua secventa:

4 6 16 17

2
Care prin interclasarea celor doua zone conduce la:
4 6 16 17

Cele doua secvente initiale din vector au devenit:

3 7 8 9 4 6 16 17

Care se interclaseaza obtinand:

3 4 6 7 8 9 16 17

Sortarea prin interclasare a doi vectori in Pascal


program interclasare;

var x,y,z:array [1..30] of integer; i,j,k,m,n:integer;

begin

write('m,n=');

readln(m,n);

{citeste elementele primului vector, validand introducerea lor}

write('x[1]=');

readln(x[1]); for i:=2 to m do repeat write('x[',i,']='); readln(x[i]); until x[i]>x[i-1];

{citeste elementele celui de-al doilea vector, validand introducerea lor}

write('y[1]='); readln(y[1]); for j:=2 to n do repeat write('y[',j,']='); readln(y[j]); until y[j]>y[j-1];

{interclasarea }

i:=1; j:=1; k:=0;

while (i<=m) and (j<=n) do

if x[i]<y[j] then

3
begin k:=k+1; z[k]:=x[i]; i:=i+1; end

else

begin k:=k+1; z[k]:=y[j]; j:=j+1; end;

{adaugam elementele ramase neparcurse din unul dintre vectorii dati}

if i<=m then while i<=m do begin k:=k+1; z[k]:=x[i]; i:=i+1; end;

if j<=n then while j<=n do begin k:=k+1; z[k]:=y[j]; j:=j+1; end;

for i:=1 to k do write (z[i], ' ');

end.

4
Sortarea prin interclasare
MergeSort
Informaii generale
Aplicaii
Vizualizare animatie
algoritm
Google
Informaii generale:
Definim interclasarea a dou liste sortate ca fiind operaia prin
care obinem o list sortat ce conine toate elementele listelor de intrare.
Sortarea prin interclasare utilizeaza metoda Divide et Impera:
-se mparte vectorul n secvene din ce n ce mai mici, astfel nct fiecare
secven s fie uor ordonat la un moment dat, apoi interclasat cu o alt
secven din vector, de asemenea ordonat.
-practic, interclasarea va ncepe cnd se ajunge la o secven format din
doua elemente. Cele doua secvente se vor interclasa i vor alctui un
subir ordonat din vector, mai mare, care, la rndul lui se va interclasa cu
subirul corespunzator obinut n acelai mod, .a.m.d.
Prezentarea algoritmului:
Ideea este de a utiliza interclasarea n etapa de asamblare a
soluiilor: n urma rezolvrii recursive a subproblemelor obinute prin
aplicarea tehnicii de programare Divide et Impera rezult liste ordonate
i prin interclasarea lor obinem lista iniial sortat.
Algoritmul de sortare implic trei etape:

irul este mprit pn la jumtate n dou subiruri de lungimi egale


(sau care difer cu cel mult o unitate), apoi prin recursivitate, cu
subirurile obinute se procedeaz la fel, pn ce subirurile au
lungime 1 sau cel mult 2 elemente;
cele dou subiruri corespunztoare ultimului apel recursiv sunt
sortate;
subirurile sortate se interclaseaz, prin revenirea din recursivitate
reconstruindu-se treptat tot vectorul iniial sortat;

5
Problema interclasrii a doi vectori sortai a i b se rezolv astfel:
-se utilizeaz un vector intermediar, c;
-se compar elementul de pe poziia nti din primul vector cu elementul
de pe poziia nti din al doilea vector; dac este mai mic elementul
primului vector, acesta se copiaz n vectorul c, apoi se crete indicele de
parcurgere astfel nct la urmtoarea comparaie s indice cel de-al doilea
element; dac este mai mic elementul din b, se va copia el n c, iar
indicele de parcurgere al lui b se incrementeaz pentru a selecta al doilea
element din b;
-prin comparaii succesive, se construiete vectorul c ordonat, pn se
termin elementele din a sau b; elementele rmase n b, sau a, dup caz,
se vor copia n ordine n c;

Exemplu1: Fie vectorul de sortat 2, 9, 5, 3, 7, 1, 6, 4

irul de intrare 2, 9, 5, 3 --- 7, 1, 6, 4

2, 9 --- 5, 3 si 7, 1 --
mprire (1) - 6, 4

2 --- 9 si 5 --- 3 si 7 ---


mprire(2) 1 si 6 --- 4

Sortare(2) se
face direct, 2 --- 9 si 3 ---
deoarece 5 si 1 --- 7 si 4 --- 6
subirurile au
maxim 2
elemente fiecare
2 , 3, 5,
9 si 1 ,4 ,6
Interclasare (2) ,7

Interclasare(1) 1, 2, 3, 4, 5, 6 ,7,9

irul final 1 2 3 4 5 6 7 9

Exemplu2: Reamintesc interclasarea.

a: 1 2 Se compar a[1] cu b[1]; se va

6
478 copia n c elementul cel mai mic,
9 respectiv a[1]; se va indica
urmtorul element din vectorul a
b: 3 5
6
c: 1
a:
124
789 Se compar a[2] cu b[1]; se va
copia n c elementul a[2] i se va
b: 3 5
indica n continuare a[3]
6
c: 1 2
a: 1
247
89 Se compar a[3] cu b[1]; se va
copia n c elementul b[1] i se va
b: 3 5
indica b[2] pentru urmtoarea
6
comparaie
c: 1 2
3
a: 1
247
89
Se compar a[3] cu b[2]; se va
b: copia n c elementul a[3], i se
356 indic a[4]
c: 1 2
34
a: 1 2
478
9
Se compar a[4] cu b[2]; se trece
b:
n c elementul b[2]; se indic b[3]
356
c: 1 2
345
a: 1 2 Se compar a[4] cu b[3]; se trece
478 n c b[3]; se termin vectorul b,
9 deci se copiaz n c toate

7
b: 3 elementele rmase neparcurse n
56 a;

c: 1 2
345
6
c: 1 2 3 4 5 6 7 8 9

Varianta pseudocod a algoritmului:


procedura mergeSort(x,st,dr);
dac st < dr atunci
m[(st+dr)/2]
mergeSort(x,st,m);
mergeSort(x,m+1,dr)
interclaseaz subvectorii (x[st],,x[m]),(x[m+1],x[dr]) ;
sfrit dac;
sfrit mergeSort;
Pentru a stabili complexitatea algoritmului de sortare prin
interclasare, remrcam urmatoarele:
- pentru un vector cu n elemente, numrul de njumtiri succesive pn
se ajunge la subvectori de lungime 1 sau 2 este de aproximativ log2n i nu
depinde de valorile din vector;
- la fiecare din aceste divizri succesive, se mut din x ntr-un vector
auxiliar pentru interclasare i invers n total n elemente.
n consecin, numarul de operaii elementare executate este
de ordinul O(nlog2n).
Constatm deci c, pentru tablouri cu numr mare de componente,
timpul de calcul este mult mai mic n cazul sortrii prin interclasare, dect
n cazul folosirii algoritmilor simpli, cum ar fi cel al seleciei, inseriei sau al
bulelor, a cror complexitate este O(n2).
Algoritmul de sortare prin interclasare consum ns de dou ori
mai mult memorie dect cei simpli mentionai, deoarece necesit spaiu
suplimentar pentru vectorul auxiliar .
Implementare C++: Implementare Pascal:
int x[20], n; type vector=array [1..20] of
void sort(int st, int dr, int x[20]){ integer;
int aux; var i,n:integer; x,b:vector;

8
if (x[st]>x[dr]) { procedure sort(st,dr:integer);
aux=x[st]; var aux:integer;
x[st]=x[dr]; begin
x[dr]=aux;} if x[st]>x[dr] then
} begin
void interclasare(int st, int dr, int m, aux:=x[st]; x[st]:=x[dr]; x[dr
int x[20]){ ]:=aux;
int b[20], i, j, k; end;
i=st; j=m+1; k=1; end;
while(i<=m && j<=dr) procedure interclasare(st,dr,m:
if(x[i]<=x[j]){ integer);
b[k]=x[i]; i++; k++; var i, j, k:integer;
else {b[k]=x[j]; j++; k++; } begin
i:=st; j:=m+1; k:=1;
if(i<=m) while (i<=m) and( j<=dr) do
for(j=i;j<=m;j++) { b[k]=x[j]; if x[i]<=x[j] then
k++; } begin
else b[k]:=x[i]; i++; k++;
for(i=j;i<=dr;i++) { b[k]=x[i]; end
k++; } else begin
k=1; b[k]:=x[j]; j++; k+
for(i=st;i<=dr;i++){ +;
x[i]=b[k]; end;
k++; } if i<=m then
} for j:=i to m do begin
void divimp(int st, int dr, int x[20]){ b[k]:=x[j]; k++
int m; ;
if((dr-st)<=1) sort(st, dr, x); end;
else {m=(st+dr)/2; else
divimp(st,m,x); for i:=j to dr do begin
divimp(m+1,dr,x); b[k]:=x[i]; k++
;
interclasare(st, dr, m, x);
end;
}
k:=1;
}
for i:=st to dr do
void main(){
begin x[i]:=b[k]; k++; end;
int i;
end;

9
cin>>n; procedure divimp(st,
for(i=1;i<=n;i++) cin>>x[i]; dr:integer);
divimp(1, n, x); var m:integer;
for(i=1;i<=n;i++) cout<<x[i]<< ; begin
} if (dr-st)<=1 then sort(st, dr);
else begin
m:=(st+dr) div 2;
divimp(st,m);
divimp(m+1,d
r);
interclasare(
st, dr, m);
end;
end;
begin
readln(n);
for i:=1 to n do readln(x[i]);
divimp(1,n);
for i:=1 to n do write(x[i] , ) ;
end.

Mergi la pagina METODE DE SORTARE

Aplicatii
Aplicaie1: Se citesc n numere complexe din fiierul date.in si dou
numere reale a,b.
S se scrie n fiierul date.out n ordine cresctoare modulele numerelor
complexe care nu aparin intervalului [a,b].
Program C++: Program Pascal:
#include <fstream.h> PROGRAM MergeSort1;
#include <iomanip.h> TYPE complex=RECORD
ifstream fin(date.in); re, im : REAL;
ofstream fies(date.out); END;
struct complex{float re, im;}; vectorc=ARRAY[1..100] OF complex;
void citirec (complex &c){ vectorr=ARRAY[1..100] OF REAL;

10
fin>>c.re>>c.im; } VAR c:vectorc; x:vectorr; a,b:REAL; i, k,
void citire(int &n, complex n:INTEGER;
x[100], float &a, float &b){ PROCEDURE citire (VAR n:INTEGER;
int i; VAR x:vectorc; VAR a,b:REAL);
fin>>n; VAR i:INTEGER; fin:TEXT;
for(i=1; i<=n; i++) citirec(x[i]); BEGIN
fin>>a>>b; } ASSIGN (fin, date.in);
float modul (complex c) { RESET(fin);
return sqrt(c.re*c.re +c.im*c.im); READ(fin, n);
} FOR i:=1 TO n DO READ(fin, x[i].re,
void intercl(int a[100], int s, int x[i].im);
m, int d){ READ(fin, a, b); CLOSE (fin); END;
int i,j,k, b[100]; FUNCTION modul (c: complex):real;
i=s; j=m+1; k=1; BEGIN
while (i<=m && j<=d) modul:=sqrt(c.re*c.re+c.im*c.im); END;
if (a[i]<a[j]) b[k++]=a[i++]; PROCEDURE intercl(VAR
else b[k++]=a[j++]; a:vectorr; s,m,d:INTEGER);
while (i<=m) b[k++]=a[i++]; VAR i,j,k:INTEGER; b:ARRAY[1..100] OF
INTEGER;
while (j<=d) b[k++]=a[j++];
BEGIN
k=1;
i:=s; j:=m+1; k:=1;
for (i=s; i<=d; i++) a[i]=b[k++];}
WHILE (i<=m) AND (j<=d) DO
void mergesort (int a[100], int s,
int d) { IF a[i]<a[j] THEN
int m; BEGIN
if (s<d) { b[k]:=a[i]; i:=i+1; k:=k+1;
m=(s+d)/2; END
mergesort(a,s,m); ELSE
mergesort(a, m+1, d); BEGIN
intercl(a,s,m,d); } } b[k]:=a[j]; j:=j+1; k:=k+1;
void scriere (float END;
a[1000], int n){ WHILE i<=m DO
int i; BEGIN
for(i=1; i<=n; i++) b[k]:=a[i]; i:=i+1; k:=k+1;
fies<<fixed<<setprecision(3)<<a[ END;
i]<< ; } WHILE j<=d DO
void main () { BEGIN
complex c[100];

11
float a, b, x[100]; b[k]:=a[j]; j:=j+1; k:=k+1;
int i, k=0, n; END;
citire (n, c, a, b); k:=1;
for (i=1; i<=n; i++) FOR i:=s TO d DO a[i]:=b[k]; END;
if (modul(c[i]) modul(c[i]>b)) PROCEDURE MergeSort(a:vectorr; s,d:I
x[++k]=modul(c[i]); NTEGER);
mergesort(x,1,k); VAR m: INTEGER;
scriere (x, k); BEGIN
fin.close(); IF s
fies.close(); } BEGIN
m:=(s+d) DIV 2;
MergeSort(a,s,m);
MergeSort(a,m+1,d);
intercl(a,s,m,d);
END;
END;
PROCEDURE scriere (a:vectori;
n:INTEGER);
VAR i:INTEGER; fies:TEXT;
BEGIN
ASSIGN (fies, date.out);
REWRITE(fies);
FOR i:=1 TO n DO WRITE(fies, a[i], );
CLOSE(fies); END;
BEGIN
citire (n,c,a,b);
FOR i:=1 TO n DO
IF (modul(c[i])<a) OR
(modul(c[i]>b) THEN
BEGIN
k:=k+1; x[k];=modul(c[i]);
END;
MergeSort (x,1,k);
scriere (x,k);
END.

12
13

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