You are on page 1of 11

Universidade Federal de Itajub

COUNTING SORT

Alunos: Ivan Bravin Pires Costa - 16914 Luiz Paulo Grillo Brando - 16925 Curso: Engenharia da Computao

Itajub Novembro 2010

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 ficaria 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 fim 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 reconfigurar 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 openOffice, 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 openOffice, 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 ficam 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 ficam 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 1 2 3 4 5 6

hlice
5

gs
4

tocha
6

armrio
1

vincola
7

dado
3

boca
2

Contagem de Ocorrncias
0 1 2 3 4 5 6

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


0 1 2 3 4 5 6

Ordenao
Passo 1 vetor A
0 1 2 3 4 5 6

hlice
5

gs
4

tocha
6

armrio
1

vincola
7

dado
3

boca
2

vetor B
0 1 2 3 4 5 6

boca

vetor C
0 1 2 3 4 5 6

Passo 2 vetor A
0 1 2 3 4 5 6

hlice
5

gs
4

tocha
6

armrio
1

vincola
7

dado
3

boca
2

vetor B
0 1 2 3 4 5 6

boca

dado

vetor C
0 1 2 3 4 5 6

Aps os outros passos vetor A


0 1 2 3 4 5 6

hlice
5

gs
4

tocha
6

armrio
1

vincola
7

dado
3

boca
2

vetor B
0 1 2 3 4 5 6

armrio

boca

dado

gs

hlice

tocha

vincola

vetor C
0 1 2 3 4 5 6

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 final 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) = Complexidade (n): Inicializao = 1 Comparaes = n Incremento = n Operaes = 3 (n) = 1 + 3*n (n) + (n) + (n) + (n)

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

Complexidade

(n): Inicializao = 1 Comparaes = n Incremento = n Operaes = 3 (n) = 1 + 3*n

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

Complexidade

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

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

Complexidade

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

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

Deste modo a complexidade total ser: (n) = 1 + 3*( n-1) + 1 + 3*n + 1 + 3*n + 1 + 4*n (n) = 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> #define 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++) aux[i+1]+=aux[i]; //ordena os indices do final para o inicio for(i = MAX- 1;i >= 0;i--) VectorSort[--aux[Base[i].number]] = Base[i]; } int main (void) { FILE * arq = fopen("openOffice194M.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