Você está na página 1de 16

Universidade do Estado de Santa Catarina

COUNTING SORT

Alunos: Alexsandro Peger


Diogo Raimondi Borges
Curso: Tecnologia em Anlise e Desenvolvimento de Sistemas

Joinville
Novembro 2015

Explicao geral
Seja o vetor v desordenado de tamanho n:
v[0]

v[1]

v[2]

... v[n-2]

v[n-1]

v[n]

A ordenao por contagem assume que cada um dos elementos do vetor,


pode ser representado por um numero inteiro, no intervalo de 1 k (k
representa o maior elemento do vetor).
O mtodo consiste em determinar a quantidade de elementos menores do
que um certo elemento x1, para determinar em qual posio do vetor
ordenado esse elemento deve ser inserido.

O Funcionamento
O CountingSort faz uso de 3 vetores:
vetA: um vetor de tamanho n que ser o vetor a ser ordenado;
vetB: um vetor de tamanho n que ser o vetor utilizado para a ordenao
dos elementos;
vetC: um vetor de tamanho k (valor do maior elemento do vetor de
entrada), que ser utilizado para a contagem da quantidade de vezes que
cada elemento aparece no vetor de entrada e a posio onde ele deve ser
inserido no vetor ordenado.
O mtodo pode ser dividido em X passos: Inicializao dos vetores, contagem do
nmero de ocorrncias de cada elemento, contagem da quantidade de nmeros
menores e ordenao.
1.

Inicializao
Esse passo extremamente simples: O vetor vetA contm os elementos
desordenados e os vetores vetB e vetC devem ser inicializados com 0.

Obs: Note que o vetor C tem 6 posies (o maior elemento do vetor de


entrada 6), em regra, pega-se o maior elemento subtrai do menor e soma
1, assim temos o tamanho k do vetor c. ( MAIOR MENOR ) + 1 = k

2.

Contagem de ocorrncias
Nesse passo feita a contagem de quantas vezes cada elemento do vetor
de entrada aparece.
Ex: No vetor A, o nmero 1 aparece uma vez apenas, portanto o valor da
posio 0 do vetor C ser 1. O nmero 2 aparece quatro vezes, portanto o
valor da posio 1 do vetor C ser 4, e assim por diante.

Obs: Note que como o elemento 4 no est presente no vetor A, a posio


3 do vetor C continua com 0, sendo que o ndice de cada elemento do vetor
C somado com 1 representa o prprio elemento em A.
Obs2: No cdigo caria um for de 0 at N onde: C[ A[i] ]++;
3.

Contagem de nmero menores


Nesse passo possvel saber a quantidade de elementos menores do que
cada elemento do vetor: basta somar cada elemento do vetor C com o seu
elemento anterior.
Ex: possvel saber, olhando para a posio 0 do vetor C, que s existe 1
nmero menor que o n 2. Olhando para a posio 1 do vetor C, possvel
saber que existem 5 nmeros menores do que o n 3 e assim por diante.

Obs: A expresso que representa esta parte do cdigo um for de 0 at o


tamanho K-1 , somando o passo i+1 com ele mesmo e com seu anterior:
C [i+1] += C[i]

4.

Ordenao
Agora o algoritmo vai percorrendo o vetor A do seu m at o inicio e
ordenando os nmeros no vetor B.

Ex: Comeando pela posio 9 do vetor A. O elemento 3


No ndice 2 do vetor C (nmero de ocorrncias do nmero 3 no vetor A) o
nmero 7.
Agora o ndice 2, decrementada em -1 no vetor C sendo que muda de 7
para 6.
O nmero 3 inserido na posio 6 do vetor.

E assim feito com cada elemento do vetor,at que o vetor esteja


ordenado

Obs: No cdigo esse ultimo passo pode ser traduzido como um for de N-1
at 0, f azendo o calculo: B[ --C[ A[i] ] = A[i];

Aspectos positivos

Ordena vetores em tempo linear para o tamanho do vetor inicial;

No realiza comparaes;

um algoritmo de ordenao estvel;

Aspectos Negativos

Necessita de dois vetores adicionais para sua execuo, utilizando, assim, mais
espao na memria.

Particularidades para implementar o CountingSort


com String
Na implementao com string, o primeiro passo recongurar as
bases de dados, de tal forma que cada palavra tenha associada a ela um
numero inteiro, referente a seu tamanho ou ordenao.
No caso, para usar as bases de dados do openOce, foi necessrio
utilizar um algoritmo que associasse a cada palavra um numero, referente
a sua posio em um vetor ordenado. Nesse algoritmo foi primeiro gerado
um vetor A com as palavras ordenadas usando o quickSort, depois
comparando com a base original openOce, gerou-se um base onde cada
palavra tinha um numero inteiro, representando sua posio no vetor A
ordenado, como no exemplo abaixo da base de dados de 194M:
bentil 71511 adar 30657 darfuost 106533 aminopirinu 42846 angisilo
46719
Com a base de dados devidamente alterada, criou-se uma estrutura
de dados (CountingSort) , aonde cada palavra estava com seu respectivo
nmero. Assim os vetores A e B, so vetores do tipo CountingSort, como
demostrado abaixo:
typedef struct{
int number; char palavra[50];
}CountingSort;
CountingSort A[MAX];
CountingSort B[MAX];
Aps isso o mtodo feito usando o number do vetor A e B, e
procedendo normalmente como para um vetor de inteiros.
Aspectos positivos:

Os tempos da ordenao cam absurdamente rpidos, uma vez que, a base


de dados das palavras venha com a informao de um numero inteiro que
represente ela, e seja compatvel com sua ordenao.

Mantm as caractersticas da ordenao com inteiros

Aspectos negativos:

As bases de dados cam maiores, como tambm a memria utilizada no processo de


ordenao do vetor A e B;

Na maioria das vezes a obteno do numero que represente a palavra, no


trivial, e despende um consumo de tempo muito grande para ser gerado,
alem do mais, tem-se que utilizar um mtodo de ordenao auxiliar e
comparaes;
Obs: A medio dos tempos no se levou em conta o tempo para a criao
das bases de tempo, este processo tem O(n), e levou muito mais tempo para
gerar a base de 194M que para ordenar todos as bases geradas, uma vez que
na obteno das bases teve tempo da ordem de dezenas de minutos, e na
ordenao dessas bases, dezenas e centenas de milisegundos.

Simulao com String


Vetor Inicial
hlice

gs

tocha

armrio

vincola

dado

boca

Associando os nmeros
0

hlice

gs

tocha

armrio

vincola

dado

boca

Contagem de Ocorrncias
0

1
1
1
1
1
Obs: Note que o vetor tem o tamanho do maior nmero
associado: 6

hlice

gs

tocha

armrio

vincola

dado

boca

Ordenao
Passo 1 vetor A

vetor B
0

boca
vetor C
0

1
Passo 2
vetor A
0

hlice

gs

tocha

armrio

vincola dado

boca

vetor B
0

boca

dado

vetor C
0

1
1
Aps os outros
passos
vetor A

hlice

gs

tocha
6

armrio
1

vincola dado
7

boca
2

vetor B
0

armrio
vetor C

boca

dado

gs

hlice

tocha

vincola

Complexidade
O cdigo que ordena o vetor A com o mtodo CountingSort :
typedef struct
{
int number; char palavra[50];
}CountingSort;
CountingSort Base[MAX];
CountingSort VectorSort[MAX]; int aux[MAX];

void CountingSortIni()
{
int i = 0;
//inicia o vetor auxiliar for(i = 0; i <MAX;i++)

aux[i]=0;
// guarda no vetor auxiliar quantas vezes um ndice esta contido
no vetor Base for(i = 0; i < MAX;i++)
aux[Base[i].number]++;
//guarda em cada posio do vetor auxiliar a verdadeira posio
do ndice for(i = 0;i<(MAX-1);i++)
aux[i+1]+=aux[i];
//ordena os indices do nal para o inicio for(i = MAX- 1;i >= 0;i--)
VectorSort[--aux[Base[i].number]] = Base[i];
}

Clculo da Complexidade
Vamos Dividir o cdigo em 3 partes sendo cada uma delas um
for: de modo que a complexidade ser:
(n) = (n) + (n) + (n) + (n)

Complexidade (n):

for(i = 0; i <MAX;i++) Inicializao = 1

aux[i]=0; Comparaes = n
Incremento = n
Operaes = 3
(n) = 1 + 3*n

Complexidade (n):

for(i = 0; i < MAX;i++) aux[Base


[i].number]++;

Inicializao = 1
Comparaes = n

Complexidade (n):

Incremento = n
Operaes = 3

for(i = 0;i<(MAX-1);i++) aux[i+1]+=aux


[i];
(n) = 1 + 3*n

Complexidade (n):

Inicializao = 1

for(i = MAX- 1;i >= 0;i--)


VectorSort[--aux[Base
[i].number]] = Base[i];

Comparaes = n-1
Incremento = n-1
Operaes = 3
(n) = 1 + 3*( n-1)

Inicializao = 1
Comparaes = n
Incremento = n
Operaes = 4
(n) = 1 + 4*n

Deste modo a complexidade total ser:


()n = 1 + 3*( n-1) + 1 + 3*n + 1 + 3*n + 1 + 4*n
()o = 1 + 13*n

A complexidade do algoritmo O(n), ou seja,


linear.

Cdigo
include <stdio.h>
include <string.h>
include <stdlib.h>
include <ctype.h> #include<time.h>

#dene MAX 194762


typedef struct
{
int number; char palavra[50];

}CountingSort;
CountingSort Base[MAX]; CountingSort VectorSort[MAX]; int
aux[MAX];

void CountingSortIni()
{
int i = 0;
//inicia o vetor auxiliar for(i = 0; i <MAX;i++)

aux[i]=0;
// guarda no vetor auxiliar quantas vezes um indice esta contido no
vetor Base for(i = 0; i < MAX;i++)
aux[Base[i].number]++;
//guarda em cada posio do vetor auxiliar a verdadeiar posio do
indice for(i = 0;i<(MAX-1);i++)
inicio

aux[i+1]+=aux[i]; //ordena os indices do nal para o

for(i = MAX- 1;i >= 0;i--) VectorSort[--aux[Base[i].number]] = Base[i];


}
int main (void)
{
FILE * arq = fopen("openOce194M.txt","r"); char pal[50];

int numero=0,i=0;
double i1=0.0,f1=0.0;
//pega do arquivo o tamanho e a palavra while(!feof(arq))
{
fscanf(arq,"%s %d",pal,&numero); strcpy(Base[i].palavra,pal); Base
[i].number=numero;

i++;
}

i1=clock();
CountingSortIni();
f1=clock();
printf("Tempo Counting Sort: %lf ",(f1-i1)); system
("pause");
fclose(arq); return 0;

Resultados
Simulao