6.7 Metode de sortare(naive)

### **Sortarea prin interschimbare(Bubble Sort)**

> *Ideea de* baza a metodei este de a traversa tabloul şi a compara fiecare element cu
>
>
> succesorul său. Dacă nu sunt în ordinea dorita, cele două elemente se
> interschimbă între ele. Tabloul este traversat in mod repetat până când, la o
> parcurgere completă, nu se mai execută nici o interschimbare între elemente,
> fapt echivalent cu presupunerea că tabloul este sortat. Presupunand ca se doreste sortarea crescatoare a elementelor, putem observa ca
> valorile cele mai mare au tendinta de “a migra” catre capatul din
>
>
>
> dreapta, precum bulele de aer in apa.
>
>

( **5 1**
4 2 8 ) –> ( **1 5** 4 2 8 ),  primele doua elemente nu respecta relatia de
ordine dorita(v[i]>v[i+1]) si sunt interschimbate.

( 1 **5 4**
2 8 ) –>  ( 1 **4 5** 2 8 ), interschimba 5 cu 4

( 1 4 **5**
2 **8 ) –>  ( 1 4** 2 5 **8 ), interschimba 5 cu 2**

Ajunge la capatul sirului si reia, deoarece pe
parcursul traversarii au fost realizate interschimbari

A doua traversare:

( 1 **4 2** 5 8 ) –> ( 1 **2 4** 5 8 ), interschimba 4 cu 2

Ajunge la capatul sirului si reia, deoarece pe
parcursul traversarii au fost realizate interschimbari

A treia traversare:

In aceasta traversare nu se mai efectueaza
interschimbari, deci elementele sunt asezate in ordinea dorita si algoritmul se
incheie.

In cea mai elementara forma, algoritmul poate fi redat dupa cum urmeaza:

```
*citeste n*

```

```
*pentru i=1, n, 1, executa*

```

```
*citeste* v[i]

```

```
*pentru i=1, n-1, 1 executa*

```

```
*pentru* j=1, n-1, 1 executa

```

```
*daca* v[j]>v[j+1] atunci

```

```
*aux=v[j];*

```

```
*v[j]=v[j+1];*

```

```
*v[j+1]=aux*

```

```
*sfarsit daca*

```

```
*sfarsit* pentru

```

```
*sfarsit pentru*

```

Observam ca, indiferent de asezarea initiala a
valorilor in vector, algoritmul realizeaza n2 operatii. Se pune
astfel, problema optimizarii sale, o varianta foarte accesibila fiind aceea de
a opri traversarea vectorului in momentul in care nu se mai inregistreaza interschimbari,

```
*#include<iostream>*

```

```
*using* namespace std;

```

```
*int* main()

```

```
*{*

```

```
*int* v[10], i, n, invers, aux;

```

```
*cout<<"n=";*
cin>>n;

```

```
*for(i=1;i<=n;i++){*

```

```
*cout<<"v["<<i<<"]=";*

```

```
*cin>>v[i];}*

```

```
*do {*

```

```
*invers=1;*

```

```
*for(i=1;i<=n-1;i++)*

```

```
*if(v[i]>v[i+1]){*

```

```
*aux=v[i];*

```

```
*v[i]=v[i+1];*

```

```
*v[i+1]=aux;*

```

```
*invers=0;}*

```

```
*}*

```

```
*while(invers);*

```

```
*for(i=1;i<=n;i++)  cout<<v[i]<<" ";*

```

```
*return* 0; *}*

```

In aceasta varianta, daca valorile sunt in
ordinea dorita de la inceput, complexitatea este O(n).

### **Sortarea prin selectie**

> *Ideea de baza a acestei metode este de a determina repetititv valoarea minima si de a o plasa la inceput. Mai precis, in pasul 1, se determina valoarea subsirului v1,*
>
>

> v2,…, vn si se plaseaza pe pozitia 1. In pasul 2, se determina valoarea subsirului v2, v3…, vn si se plaseaza pe pozitia 2. Algoritmul, evident, va
> rula n-1 pasi.
>
>

> Observam ca, in urma fiecarei traversari a vectorului, acesta va fi impartit, practic,
>
>
> in doua. Subsirul v1, v2,… vi va fi sortat crescator, subisrul vi+1, vi+2, …vn
> va fi nesortat. Exemplul urmator reda aplicarea acestui algoritm, considerand
>
>
>
> ca vectorul v contine valorile: 5 1 4 2 8 .
>
>

***5 1** 4 2 8   -> 1 **5** 4 **2** 8 determina minul in pozitia a 2-a si il va muta pe pozitia 1*

1 **5** 4 **2** 8  -> 1 2 **4** 5 8 determina minimul pe pozitia a 4-a si il va muta pe pozitia a 2-a

1 2 **4** 5 8 -> 1 2 4 **5** 8 determina minimul
pe pozitia a 3-a si il va muta pe pozitia a 3-a (practic nu se modifica starea
vectorului)

1 2 4 **5** 8 -> 1 2 4 **5** 8 determina minimul
pe pozitia a 4-a si il va muta pe pozitia a 4-a (practic nu se modifica starea
vectorului)

*Algoritmul*
se opreste dupa n-1 pasi, unde n este numarul elementelor din vector.

In pseudocod algoritmul poate fi redat dupa
cum urmeaza:

```
*citeste n*

```

```
*pentru i=1, n, 1, executa*

```

```
*citeste* v[i]

```

```
*pentru i=1, n-1, 1 executa*

```

```
*min=v[i]*

```

```
*pozmin=i*

```

```
*pentru j=i+1,* n, 1 executa

```

```
*daca* v[j]< min atunci

```

```
*min=v[j]*

```

```
*pozmin=j*

```

```
*sfarsit daca*

```

```
*sfarsit* pentru

```

```
*aux=v[i]*

```

```
*v[i]=min*

```

```
v*[pozmin]=aux*

```

```
*sfarsit pentru*

```

*Complexitatea*
acestui algoritm este O(n2). Implementarea lui poate fi lasata ca
exercitiu.

### Sortarea prin insertie

> Acest algoritm urmareste inserarea, pe rand, a
>
>
> fiecarui element al vectorului in pozitia in care toate elementele aflate la
>
>
>
> stanga sunt mai mici decat el. Sa luam spre exemplu sirul 5 1 4 2 8.
>
>

> Vom incepe cu cel de-al doilea element, primul
>
>
> fiind, in momentul initial, mai mare decat toate elementele aflate in stanga
> lui. Cum valoarea celui de-al doilea element este 1, il vom insera in vector
>
>
>
> inaintea valorii 5
>
>

5 **1** 4 2 8   ->  **1** 5

4 2 8

Luand in considerare al treilea element, 4,
observam ca trebuie sa-l introducem inaintea valorii 5

1 5 **4**
2 8   -> 1 **4** 5 2 8

Urmatorul element este 2, iar el va fi inserat
inaintea lui 4

1 4 5 **2**
8   -> 1 **2** 4 5 8

Ultima valoare din sir, 8, este lasata pe loc,
fiind mai mare decat toate elementele precedente

1 2 4 5 **8**
  -> 1 2 4 5 **8**

Observam ca, la fiecare pas, algoritmul creaza doua subsiruri in sirul initial. Cel aflat la stanga elementului curent, care
este sortat si cel aflat la dreapta, cu elemente asezate in ordinea initiala. Complexitatea
algoritmului este O(n2), cazul cel mai nefavorabil fiind acela in
care elementele sirului sunt in ordine descrescatoare.

```
*citeste n*

```

```
*pentru i=1, n, 1, executa*

```

```
*citeste v[i]*

```

```
*pentru i=2, n,1 executa*

```

```
*aux = a[i]*

```

```
*j := i-1;*

```

```
*cat timp (j>=1) si (a[j]>aux)*

```

```
   *a[j+1] := a[j];*

```

```
   *j := j-1;*

```

```
*sfarsit cat timp*

```

```
a[j+1] := aux;

```

```
*sfarsit pentru;*

```

Redam, mai jos, o modalitate de implementare a
algoritmului.

```
*#include <iostream>*

```

```
*using namespace std;*

```

```
*int v[10],i,j,n,aux;*

```

```
*int main(){*

```

```
*cout<<"n=";*

```

```
*cin>>n;*

```

```
*for(i=1;i<=n;i++){*

```

```
      *cout<<"v["<<i<<"]=";*

```

```
      *cin>>v[i]; }*

```

```
*for(i=2;i<=n;i++){*

```

```
  *aux = v[i];*

```

```
  *j= i-1;*

```

```
  *while((j>=1)*&& (v[j]>aux)){

```

```
      *v[j+1]= v[j];*

```

```
      *j= j-1;}*

```

```
  *v[j+1]= aux;*

```

```
*}*

```

```
*for(i=1;i<=n;i++)* cout<<v[i]<<" ";

```

```
*return 0;*

```

```
*}*

```