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:

 

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

 

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

 

 

O solutie de implementare:

 

int a[1000],n;

 

void interclas(int i,int m,int j)

{int b[1000];

int x=i;

int k=1;

int 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);

     interclas(i,m,j);}

}

 

 

void main()

{clrscr();

cout<<"n=";

cin>>n;

for(int i=1;i<=n;i++)

        {cout<<"a["<<i<<"]=";

         cin>>a[i];

        }

divimp(1,n);

for(i=1;i<=n;i++)

   cout<<a[i]<<' ';

getch();

}

 

 

Pentru a stabili complexitatea algoritmului de sortare prin interclasare, remărcam urmatoarele:

 

  - pentru un tablou cu n elemente, numărul de înjumătățiri succesive până se ajunge la zone de lungime 1 sau 2 este de aproximativ log2n;

  - la fiecare din aceste divizări succesive, se mută din tab în tab1 și invers în total n elemente.

In consecinta, numarul de operatii elementare executate este de ordinul O(n.log(n)).

  Mai riguros, daca notam cu C(n) numarul de operații elementare pentru sortarea unui tablou cu n componente și avem în vedere că, la fiecare pas al algoritmului, se fac doua invocări recursive ale metodei de sortare și o interclasare, iar interclasarea are complexitatea n, atunci

C(n) = 2.C(n/2)+n

Continuând acest raționament, putem scrie

C(n) = 2(2C(n/4)+n/2)+n = 4C(n/4) + n + n

Algoritmul se oprește după log2(n) astfel de pași, când se obține

C(n) = nC(n/n) + n + n + ... + n = n.log2(n)

In consecință, complexitatea algoritmului de sortare prin interclasare este O(n.log2(n)).

 

 

Constatăm deci că, pentru tablouri cu numar mare de componente, timpul de calcul este mult mai mic în cazul sortării prin interclasare, decât în cazul folosirii algoritmilor simpli, cum ar fi cel al selecției, inserției sau al bulelor, a căror complexitate este O(n2). Algoritmul de sortare prin interclasare consumă însă de două ori mai multă memorie decât cei simpli mentionați, deoarece necesită spațiu suplimentar pentru tabloul auxiliar .