Sortarea prin numărare CountSort 

 Informaţii generale:

      Această metodă constă în construirea unui nou vector, y, care are aceeaşi dimensiune ca şi vectorul de sortat, x, în care se vor memora elementele din x ordonate crescător. Fiecare element din x se compară cu celelalte elemente ale vectorului pentru a determina câte elemente mai mici decât el se află în vector. Acest element se va aşeza în vectorul sortat ţinând cont că în faţa lui trebuie să fie elementele mai mici.

Prezentarea algoritmului:

Se folosesc trei vectori:

    • vectorul sursă (vectorul nesortat): x;
    • vectorul destinaţie (vectorul sortat): y;
    • vectorul numărător (vectorul de contoare): k.

     Pentru a se cunoaşte poziţia în care va fi inserat fiecare element, se parcurge vectorul sursă x şi se numără în vectorul k, pentru fiecare element x[i], câte elemente au valoarea mai mică decât x[i]. Aşadar, elementul k[i] este un contor pentru elementul x[i], reprezentând câte elemente sunt mai mici decât el şi arată de fapt poziţia în  care trebuie copiat în vectorul y.

Se folosesc următoarele variabile de memorie:

    • x, y, k pentru vectori şi n pentru lungimea vectorilor; vectorul k fiind un vector de contoare, elementele lui se iniţializează cu 0;
    • variabila i pentru parcurgerea vectorului sursă în vederea numărării  pentru fiecare element x[i] şi apoi pentru parcurgerea vectorului sursă în vederea copierii elementelor sale în y;
    • variabila j pentru parcurgerea elementelor situate după elementul curent în vectorul sursă x: pentru fiecare comparare x[i] cu x[j], se incrementează fie k[i]  (x[i] >x[j]), fie k[j] (x[i] ≤x[j]);

 

Exemplu: Fie vectorul x=[ 7,8,2,9]

Prima parcurgere i=1 si j=2,3,4:

x:

i=1

7

8

2

9

 

 

    

        y:                                                        Parcurgere pentru numărare: dacă x[i]>x[j] atunci k[i] ←k[i]+1altfel k[j]← k[j]+1;

j=2

0

1

0

0

7>8: Nu →k[2]=k[2]+1=1

j=3

1

1

0

0

7>2: Da→k[1]=k[1]+1=1

j=4

1

1

0

1

7>9: Nu→k[4]=k[4]+1=1

 

 

 

 

 

 

 

 

A doua parcurgere i=2 si j=3,4:

x:                                                        

i=2

7

8

2

9

 

 

    

        y:                                                          Parcurgere pentru numărare: dacă x[i]>x[j] atunci k[i] ←k[i]+1altfel k[j]← k[j]+1;

j=3

1

2

0

1

8>2: Da→k[2]=k[2]+1=2

j=4

1

2

0

2

8>9: Nu→k[4]=k[4]+1=2

 

 

 

 

 

 

A treia parcurgere i=3 si j=4:

 x:

i=3

7

8

2

9

 

                                                         

   

        y:                                                          Parcurgere pentru numărare: dacă x[i]>x[j] atunci k[i] ←k[i]+1altfel k[j]← k[j]+1;    

j=4    

1

2

0

3

2>9: Nu→k[4]=k[4]+1=3

 

 

 

 

 Parcurgere pentru copiere

  

x

7

8

2

9

 

 

 

k

1

2

0

3

                          

                                 

   

       y:                    1         2        3         4                       

i=1

 

7

 

 

x[1]→  y[k[1]+1]=y[1+1]=y[2]

i=2

 

7

8

 

x[2]→  y[k[2]+1]=y[2+1]=y[3]

i=3

2

7

8

 

x[3]→  y[k[3]+1]=y[0+1]=y[1]

i=4

2

7

8

9

x[4]→  y[k[4]+1]=y[3+1]=y[4]

i=4

 

 

 

 

i=n→ terminare copiere

  

 

 

 

 

 

 

 

 

 

 

 

 

 

                                                       

 Observaţie:

            Elementul x[i] se copiază în noul vector y pe poziţia indicată de k[i], la care se adaugă valoarea 1, pentru a îi face loc elementului însuşi.

           

Varianta pseudocod a  algoritmului:

pentru  i←1,n execută    k[i]←0;      

pentru  i←1,n-1 execută

         pentru j←i+1,n execută

                   dacă x[i]>x[j] atunci k[i] ←k[i]+1

                                         altfel  k[j] ←k[j]+1;

                   sfârşit dacă;

         sfârşit pentru;

sfârşit pentru;

pentru i←1,n execută    y[k[i]+1]←x[i];    

sfârşit pentru;

pentru i←1,n execută   scrie y[i];

sfârşit pentru;

         Pentru acest algoritm de sortare nu putem spune că există caz favorabil, nefavorabil sau mediu, deoarece numărul de paşi efectuaţi este n2 indiferent de structura datelor de intrare. Aşadar, ordinul de complexitate este O(n2).

Implementare C++:

for (i=0;i<n-1;i++) k[i]=0;

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

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

                  if(x[ i ] > x[ j ]) k[ i ]++;

                  else    k[ j ]++;

for (i=0;i<n;i++)   y[k[i]]=x[i];

for (i=0;i<n;i++)  cout<<y[i]<<” “;

Implementare Pascal:

for i:=1 to n do  k[i]:=0;

for i:=1 to n-1 do

         for j:=i+1 to n do

                  if x[ i ] > x[ j ] then k[ i ]:=k[ i ]+1;

                                      else    k[ j ]:=k[ j ]+1;

for i:=1 to n do   y[k[i]+1]:=x[i];

for i:=1 to n do write (y[i],’     );

                                  Mergi la pagina METODE DE SORTARE

Aplicatii

Aplicaţie1: Se citeşte un vector a cu n elemente cifre. Afişaţi cel mai mic număr natural care se poate forma cu toate cele n cifre din vectorul a.

Exemplu: Dacă a este compus din 5 0 3 0 1, atunci numărul cerut este 10035.

Program C++:

#include <iostream.h>

#include <conio.h>

int n,i,j, a[20], b[20], k[20];

void main() {

cin>>n;

for(i=1; i<=n; i++) cin>>a[i];

for(i=1; i<=n; i++) k[i]=0;

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

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

                        if (a[i]>a[j]) k[i]++;

                        else k[j]++;

for(i=1; i<=n; i++) b[k[i]]=a[i];

if (b[1]==0){

            i=2;

while (b[i]==0) i++;

b[1]=b[i]; b[i]=0;}

for(i=1; i<=n; i++) cout<<b[i];

getch(); }

Program Pascal:

PROGRAM CountSort1;

TYPE vector= ARRAY[1..20] OF INTEGER;

VAR a,b,k:vector;

            i,j, n: INTEGER;

BEGIN

READLN(n);

FOR i:= 1 TO n DO READLN(a[i]);

FOR i:= 1 TO n DO k[i]:=0;

FOR i:= 1 TO n-1 DO

            FOR j:= i+1 TO n DO

                        IF a[i]>a[j] THEN k[i]:=k[i]+1

                        ELSE k[j]:=k[j]+1;

FOR i:= 1 TO n DO b[k[i]]:=a[i];

IF b[1]=0 THEN

            BEGIN

            i:=2;

            WHILE b[i]=0 DO i:=i+1;

            b[1]:=b[i]; b[i]:=0;

            END;

FOR i:= 1 TO n DO WRITE(b[i]);

END.

 

Aplicaţie2: Se citeşte din fişierul date.in o matrice cu n linii şi m coloane, având elemente numere întregi. Să se ordoneze crescător elementele de pe fiecare linie a matricii.

Program C++:

#include <iostream.h>

#include <conio.h>

#include

ifstream f(”date.in”);

int a[20][20],x[20], m, n, i ,j;

void countsort(int x[20]){

int k[20],y[20], i, j;

for(i=1; i<=m; i++) k[i]=0;

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

            for(j=i+1; j<=m; j++)

                        if (x[i]>x[j]) k[i]++;

                        else k[j]++;

for(i=1; i<=m; i++) y[k[i]]=x[i];

for(i=1; i<=m; i++) x[i]=y[i];}

void main() {

f>>n>>m;

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

            for(j=1; j<=m; j++)

f>>a[i][j];

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

for(j=1; j<=m; j++) x[j]=a[i][j];

countsort (x);

for(j=1; j<=m; j++) a[i][j]=x[j];

}

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

            for(j=1; j<=m; j++)

                        cout<<a[i][j]<<” ”;

            cout<<endl;}

f.close();

getch(); }

Program Pascal:

PROGRAM CountSort2;

TYPE vector= ARRAY[1..20] OF INTEGER;

VAR a:ARRAY[1..20, 1..20] OF INTEGER;

x:vector;

            i,j,m, n: INTEGER; f:TEXT;

PROCEDURE countsort (VAR x:vector);

VAR y,k:vector; i,j:INTEGER;

BEGIN

FOR i:= 1 TO             m DO k[i]:=0;

FOR i:= 1 TO m-1 DO

            FOR j:= i+1 TO m DO

                        IF x[i]>x[j] THEN k[i]:=k[i]+1

                        ELSE k[j]:=k[j]+1;

FOR i:= 1 TO n DO y[k[i]]:=x[i];

FOR i:= 1 TO n DO x[i]:=y[i];

END;

BEGIN

ASSIGN (f, ’date.in’);

READ(f, m, n);

FOR i:= 1 TO n DO

FOR j:= 1 TO m DO

 READ(f, a[i,j]);

FOR i:= 1 TO n DO

BEGIN

FOR j:= 1 TO m DO x[j]:=a[i,j];

countsort (x);

FOR j:= 1 TO m DO a[i,j]:=x[j];

END;

FOR i:= 1 TO n DO BEGIN

FOR j:= 1 TO m DO WRITE( a[i,j], ’  ’);

WRITELN;

END;

CLOSE(f);

END.

 

Observaţie: Am folosit o funcţie în care am făcut sortarea fiecărei linii în parte, sub forma vectorului x[m]. Pentru sortarea prin numărare au mai fost necesari încă doi vectori de aceeaşi dimensiune, k şi y. În Pascal a trebuit să definim tipul vector pentru a putea transmite ca parametru vectorul de lucru x[m].

 

 

Mergi la pagina METODE DE SORTARE