You are on page 1of 8

Uma WEB para Quick-Sort

Tssio a 27 de novembro de 2011

1.

Condies co

Queremos escrever um conjunto pequeno de rotinas para fazer Quick-Sort com vetores. C tambm um pequeno conjunto de procedimentos para testar e nosso algoritmo de ordenaao. Assumimos que os valores esto armazenados c a em um vetor, e que sejam comparveis usando os operadores < e . Para os a testes, vamos precisar que seja poss comparar os valores quanto ` igualdade. vel a Cabealhos inclu c dos 2 Declaraes globais 3 co Funes para ordenao 4 co ca Funes para testes 8 co Rotina principal 10

2. Cabealhos inclu c dos 2 #include <stdio.h>


See also chunk 13. This code is used in chunk 1.

3. Chegamos a um ponto importante, e a deciso do formato em que os dados a sero internamente armazenados no pode mais ser adiada. Assumimos que a a os valores so armazenados em um vetor de valores que podem ser comparados a automaticamente com os operadores relacionais < e . Para no nos prendermos a a um tipo particular, damos um nome de para o tipo de dados, permitindo assim uma mudana fcil. c a Declaraes globais 3 co typedef double valor t;
See also chunks 5 and 7. This code is used in chunk 1.

4.

Funes para ordenao 4 co ca void quick sort (valor t v[ ], int p, int r) { int q; if (p r) return; else { q = divide (v, p, r); quick sort (v, p, q 1); quick sort (v, q + 1, r); } }

See also chunk 6. This code is used in chunk 1.

5.

Declaraes globais 3 + co void quick sort (valor t v[ ], int p, int r);

6. A funo divide rearranja os elementos vp , vp+1 , . . . , vr de v[p .. r], retorca nando um valor i tal que vp , vp+1 , vi1 vi e os demais elementos sejam maiores que vi . os elementos Assumimos que p menor do que r. Funes para ordenao 4 + co ca int divide (valor t v[ ], int p, int r) { valor t valor pivot ; int i = 0, j; j = r; / O pivot poderia ser um elemento qualquer. / valor pivot = v[j]; / Guardamos o valor do pivot. / do { / Vale: v[p .. i 1] < valor pivot , e valor pivot v[j + 1..r]. / while (v[i] < valor pivot i < j) ++ i; v[j] = v[i]; j; while (valor pivot v[j] i < j) j; v[i] = v[j]; } while (i < j); v[i] = valor pivot ; return i; }

7. Declaraes globais 3 + co int divide (valor t v[ ], int p, int r);

8. Para testar se nossa rotina ordenou de fato o vetor, escrevemos agora duas rotinas, para testar se um intervalo em um vetor no-decrescente, e para e a vericar se dois vetores tm os mesmos valores. A segunda rotina assumir e a que o primeiro vetor passado est ordenado. Aqui usamos pela primeira vez as a denies de verdade e falso . co #dene verdade 1 #dene falso 0 Funes para testes 8 co int monotono (valor t v[ ], int p, int r) { while (p < r) { if (v[p] > v[p + 1]) return falso ; ++ p; } return verdade ; }
See also chunk 9. This code is used in chunk 1.

9. Vericamos a equivalncia entre os vetores do seguinte modo: contamos o e nmero de ocorrncias do menor valor presente no vetor ordenado (ou seja, o u e nmero de repeties do primeiro elemento). Varremos a seguir o outro vetor e u co contamos o nmero de ocorrncias do valor. u e Funes para testes 8 + co int mesmos elementos (valor t ordenado [ ], int ord p , int ord r , valor t nao ordenado [ ], int nord p , int nord r ) { int i = 0, j, ocorrencias = 0; i = ord p ; while (i ord r ) { ocorrencias = 0; while (ordenado [i] < ordenado [i + 1]) { ++ ocorrencias ; ++ i; } j = nord p ; while (j nord r ) { if (nao ordenado [j] ordenado [i]) ocorrencias ; ++ j; } if (ocorrencias = 0) return falso ; ++ i; } return verdade ; 3

10. Nossa rotina principal, ento, toma forma. Ela processar vrios testes, a a a cada um dos quais envolve a ordenao de um vetor (de tamanho e valores ca dados). Vamos ler linha a linha o arquivo de entrada. Cada linha contm um e nmero, e cada teste tem em sua primeira linha o nmero n (inteiro) de linhas u u que ainda devem ser lidas no teste. Cada uma das n linhas seguintes contm e um elemento do vetor a ser ordenado. A entrada termina quando n zero. e Rotina principal 10 int main (int argc , char argv ) { Variveis locais 15 a Leitura de argumentos 11 Abertura do arquivo 12 do { Leitura de teste 16 if ( Testes no acabaram 18 ) { Testar 20 a else break; while (verdade ) ; Faxina nal 14 return 0; / Trmino bem-sucedido. / e }
This code is used in chunk 1.

11. O programa recebe um unico argumento que o nome do arquivo com os e testes. Leitura de argumentos 11 if (argc < 2) { fprintf (stderr , "Epa! Falta um argumento aqui.\n"); exit (1); }
This code is used in chunk 10.

12. Abertura do arquivo 12 arquivo = fopen (argv [1], "r"); if (arquivo ) { fprintf (stderr , "Nao consegui ler o arquivo %s.\n", argc [1]); exit (1); }
This code is used in chunk 10.

13. Para a funo exit , assim como para o tipo FILE , precisamos de mais ca uma Cabealhos inclu c dos 2 + #include <stdlib.h> 4

14. Faxina nal 14 free (arquivo );


This code is used in chunk 10.

15. Variveis locais 15 a FILE arquivo = ;


See also chunk 17. This code is used in chunk 10.

16. A leitura de um teste comea com a leitura do nmero de elementos no c u vetor de teste. A seguir, alocamos o espao para armazenar os vetores, e os c populamos com valores lidos do arquivo . Este trecho deve ser modicado se valor t deixar de ser double. Leitura de teste 16 fscanf (arquivo , "%d", &n); Aloca original 19 i = 0; while (i < n) { fscanf (arquivo , "%lf", &original [i]); a ordenar [i] = original [i]; ++ i; }
This code is used in chunk 10.

17. Variveis locais 15 + a int n, i;

18.

Os testes acabam quando n for zero.

Testes no acabaram 18 a n > 0;


This code is used in chunk 10.

19. Cada teste usa um par de vetores original1 [0..n 1] original2 [0..n 1] com os mesmos elementos.

Aloca original 19 original = malloc (tamanho sizeof (valor t)); a ordenar = malloc (tamanho sizeof (valor t)); if (original ) { fprintf (stderr , "Falta memoria! Vou abortar este teste.\n"); return; } if (a ordenar ) { free (original ); fprintf (stderr , "Falta memoria! Vou abortar este teste.\n"); return; }
This code is used in chunk 16.

20. Finalmente, vamos orquestrar o teste em si! Com o que j temos em a mos, no resta muito a fazer. Ordenamos original1 e em seguida vericamos a a se possui os mesmos elementos que seu par. Caso possua, e caso seus elementos estejam em ordem no-decrescente, consideraremos que a ordenao foi feita a ca com sucesso. Testar 20 quick sort (original1 , 0, n 1); if (mesmos elementos (original1 , 0, n 1, original2 , 0, n 1) monotono (original1 , 0, n 1)) { / Sucesso! / else { fprintf (stderr , "Caro, nao me sinto bem... estou com algum problema.\n"); fprintf (stderr , "Eis os danados.\n"); fprintf (stderr , "Seq. original: "); for (i = 0; i < n; ++ i) fprintf (stderr , "%lf,", original2 [i]); fprintf (stderr , "\n"); fprintf (stderr , "Seq. reordenada: "); for (i = 0; i < n; ++ i) fprintf (stderr , "%lf,", original1 [i]); fprintf (stderr , "\n"); }
This code is used in chunk 10.

Indice Remissivo a ordenar : 16, 19. argc : 10, 11, 12. argv : 10, 12. arquivo : 12, 14, 15, 16. divide : 4, 6, 7. exit : 11, 12, 13. falso : 8, 9. fopen : 12. fprintf : 11, 12, 19, 20. free : 14, 19. fscanf : 16. i: 6, 9, 17. j: 6, 9. main : 10. malloc : 19. mesmos elementos : 9, 20. monotono : 8, 20. n: 17. nao ordenado : 9. nord p : 9. nord r : 9. ocorrencias : 9. ord p : 9. ord r : 9. ordenado : 9. original : 16, 19. original1 : 19, 20. original2 : 19, 20. p: 4, 5, 6, 7, 8. q: 4. quick sort : 4, 5, 20. r: 4, 5, 6, 7, 8. stderr : 11, 12, 19, 20. tamanho : 19. v: 4, 5, 6, 7, 8. valor pivot : 6. valor t: 3, 4, 5, 6, 7, 8, 9, 16, 19. verdade : 8, 9, 10.

List of Renements Abertura do arquivo 12 Used in chunk 10. Aloca original 19 Used in chunk 16. Cabealhos inclu c dos 2, 13 Used in chunk 1. Declaraes globais 3, 5, 7 co Used in chunk 1. Faxina nal 14 Used in chunk 10. Funes para ordenao 4, 6 co ca Used in chunk 1. Funes para testes 8, 9 co Used in chunk 1. Leitura de argumentos 11 Used in chunk 10. Leitura de teste 16 Used in chunk 10. Rotina principal 10 Used in chunk 1. Testar 20 Used in chunk 10. Testes no acabaram 18 a Used in chunk 10. Variveis locais 15, 17 a Used in chunk 10.

You might also like