Documente Academic
Documente Profesional
Documente Cultură
COUNTING SORT
Alunos: Ivan Bravin Pires Costa - 16914 Luiz Paulo Grillo Brando - 16925 Curso: Engenharia da Computao
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] ]++;
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.
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.
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
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
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)
Complexidade
Complexidade
(n): Inicializao = 1 Comparaes = n-1 Incremento = n-1 Operaes = 3 (n) = 1 + 3*( n-1)
Complexidade
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];
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