Você está na página 1de 24

UNIVERSIDADE FEDERAL DO ESPIRITO SANTO CENTRO DE CIENCIAS AGRARIAS DEPARTAMENTO DE COMPUTAO CURSO DE SISTEMAS DE INFORMAO DISCIPLINA DE PROGRAMAO I

MERGESORT

ALEGRE 2012

ANA PAULA SIMIQUELI BORGES DILHERMANDO VIEIRA STOCK TALITA CUMI GOUVEIA ROZADO THAISLANE ROSA DE SOUZA COSTA

MERGESORT

Trabalho apresentado disciplina de Programao I sob orientao da professora Simone Dornellas

ALEGRE 2012

Sumrio
1 Introduo .................................................................................................................................. 5 2 O algoritmo................................................................................................................................. 6 2.1 Introduo ao MergeSort .................................................................................................... 6 2.2 Significado do MergeSort .................................................................................................... 6 2.3 Classificao ........................................................................................................................ 6 2.4 Aplicando Dividir para conquistar no MergeSort ................................................................ 7 2.5 Complexidade...................................................................................................................... 7 2.6 Vantagens e Desvantagens ................................................................................................. 8 3 Funcionamento do MergeSort ................................................................................................... 9 3.1 Pseudocdigo ...................................................................................................................... 9 3.2 Cdigo em Pascal.............................................................................................................. 10 4. Parte Dois ................................................................................................................................ 12 4.1 O Problema........................................................................................................................ 12 4.2 Soluo .............................................................................................................................. 13 5 Referncias bibliogrficas ........................................................................................................ 24

ndice de Ilustraes

Figura 1: Funcionamento do algoritmo mergesort. ...................................................................... 7

1 Introduo
Ordenao o ato de se colocar os elementos de uma sequncia de informaes, ou dados, em uma ordem predefinida. O termo tcnico em ingls para ordenao sorting, cuja traduo literal "classificao". Um algoritmo de ordenao na rea de computao um algoritmo que coloca os elementos de uma dada sequncia em certa ordem. Existem vrios algoritmos destinados a este fim, a maioria deles baseado na ideia de insero, seleo e permutao. Existem mtodos simples como Insertion sort , Selection sort e Bubble sort e mtodos sofisticados como quick sort, shell sort e merge sort. Neste trabalho falaremos em especial sobre o Merge Sort.

2 O algoritmo
2.1 Introduo ao MergeSort
Ainda existe uma discusso sobre o assunto, mas apareceram evidncias de que o algoritmo foi proposto por John Von Neumann em 1945. A atribuio a ele veio de Knuth, que argumentou no seu livro Arte de Programao Computacional: Ordenando e Procurando que Von Neumann foi o primeiro a descrever a ideia.

2.2 Significado do MergeSort


O processo de Seleo e juno so complementares porque: Seleo: divide a lista em duas outras independentes. Juno: une duas listas independentes em uma lista maior ordenada. Isso insinua que o Mergesort consiste em duas chamadas recursivas e um processo de juno. Ento, Mergesort um algoritmo recursivo, que implementado dividindo uma sequncia original em pares de dados, ordena-as e depois as agrupa em sequncias de quatro elementos, e assim por diante, at ter toda a sequncia dividida em apenas duas partes. Assim, sua ideia bsica que muito fcil criar uma sequncia ordenada a partir de duas outras tambm ordenadas.

2.3 Classificao
- Ordenao por partio O Mergesort classificado como ordenao por partio, que parte do princpio de "dividir para conquistar". Este princpio uma tcnica que foi utilizada pela primeira vez por Anatolii Karatsuba em 1960 e consiste em dividir um problema maior em problemas pequenos, e sucessivamente at que o mesmo seja resolvido diretamente. Esta tcnica realiza-se em trs fases: Diviso: o problema maior dividido em problemas menores e os problemas menores obtidos so novamente divididos sucessivamente de maneira recursiva. Conquista: o resultado do problema calculado quando o problema pequeno o suficiente. Combinao: os resultados dos problemas menores so combinados at que seja obtida a soluo do problema maior. Algoritmos que utilizam o mtodo de partio so caracterizados por serem os mais rpidos dentre os outros algoritmos pelo fato de sua complexidade ser, na maioria das situaes, O(nlogn).

2.4 Aplicando Dividir para conquistar no MergeSort


Dividir: dividir a lista em duas listas com cerca da metade do tamanho. Conquistar: dividir cada uma das duas sublistas recursivamente at que tenham tamanho um. Combinar: fundir as duas sublistas de volta em uma lista ordenada. Sendo estvel na maioria de suas implementaes, onde estas podem ser iterativas ou recursivas. Sua desvantagem o fato de utilizar uma estrutura auxiliar, ocupando o dobro de memria. interessante destacar suas caractersticas em cima do paradigma de "diviso para conquista": Dividir: se a sequncia tiver mais de um elemento, divida em duas partes. Conquistar: ordene cada subsequncia em separado usando mergesort. Combinar: junte as duas subsequncias em uma sequncia ordenada. A operao de fuso merge, do mergesort, muito utilizada na busca online, aonde os dados chegam de blocos em blocos, so ordenados por qualquer mtodo e depois fundidos pela mesma. No entanto, esta abordagem pode demandar muito tempo e espao de armazenamento se os blocos recebidos forem pequenos em comparao com os dados ordenados.

Figura 1: Funcionamento do algoritmo mergesort.

2.5 Complexidade
Primeiramente vamos definir o que melhor, mdio e pior caso para o MergeSort. Melhor Caso nunca necessrio trocar aps comparaes. Mdio Caso h necessidade de haver troca aps comparaes. Pior Caso sempre necessrio trocar aps comparaes.

Para o MergeSort no tem tanta importncia se o vetor est no melhor, mdio ou pior caso, porque para qualquer que seja o caso ele sempre ter a complexidade de ordem n*logn, como pode ser verificado na tabela abaixo:
Melhor caso

Mdio caso Pior caso

O(n log2 n) O(n log2 n) O(n log2 n)

Isso pelo motivo de que o MergeSort independentemente em que situao se encontra o vetor, ele sempre ir dividir e intercalar. Na prtica, difcil (seno impossvel) prever com rigor o tempo de execuo de um algoritmo ou programa. O tempo vai depender de varias constantes, como por exemplo, o tempo de processamento de cada computador, do algoritmo implementado.

2.6 Vantagens e Desvantagens


Vantagens: - til para ordenao externa; - Pior caso: O(n log2 n) - Aplicaes com restrio de tempo - Fcil implementao Desvantagens: - Utiliza memria auxiliar - Alto consumo de memria Outras Informaes Eficiente para ordenar listas:

3 Funcionamento do MergeSort
3.1 Pseudocdigo
MergeSort (vetor, Inicio, fim) Se inicio < fim ento meio<-(inicio +fim) div 2 MergeSort (vetor, inicio, meio); MergeSort (vetor, meio+1, fim); Merge (vetor, inicio, meio, fim); fim-se Merge (vetor, inicio, meio, fim); i<- inicio j<- meio+1; k<-1; enquanto (i<= meio) e (j<=fim) faa se vetor[i] < vetor [j] ento aux[k] <- vetor[i]; i <- i+1; senao aux[k] <- vetor[j]; j <- j+1; fim-se k<-k+1; fim-enquanto enquanto (i<= meio) faa aux[k] <-vetor[i]; k<-k+1; i<-i+1 ; fim-enquanto enquanto (j<= fim) faa aux[k] <-vetor[j]; k<-k+1; j<-j+1; fim-enquanto para k<-ini ate fim do vetor[k]<-aux[k] fim-para

3.2 Cdigo em Pascal


program MergeSort; uses crt; type vetor= array[1..10] of integer; procedure merge(var v:vetor; ini,meio,fim: integer); var aux:vetor; i,j,k: integer; begin i := ini; j := meio + 1; k := ini; while ((i <= meio) and (j <= fim)) do begin if (v[i] < v[j]) then begin aux[k] := v[i]; I := i + 1; end else begin aux[k] := v[j]; j := j + 1; end; k := k + 1; end; while (i <= meio) do begin aux[k] := v[i]; k := k + 1; i := i + 1; end; while (j <= fim) do begin aux[k] := v[j];

k := k + 1; j := j + 1; end; for k := ini to fim do v[k] := aux[k]; end; procedure mergesort(var v:vetor; i, f:integer); var m: integer; begin if i<f then begin m:=(i+f) div 2; mergesort(v, i, m); mergesort(v, m+1, f); merge(v,i,m, f); end; end; var i:integer; vetorzin:vetor; begin for i:=1 to 10 do readln(vetorzin[i]); mergesort(vetorzin, 1, 10); for i:=1 to 10 do writeln(vetorzin[i]); readkey; end.

4. Parte Dois
4.1 O Problema
Os juzes de uma maratona de surf precisam da sua ajuda. Os juzes por muito tempo utilizaram um programa chamado de quebra_galho que utilizava vetores de registros para armazenar as notas e outras informaes dos participantes da maratona. Com o passar do tempo notaram que toda vez que o computador era desligado as informaes dos participantes eram perdidas e se tornou muito custoso ter que digitar todas as informaes todas as vezes que precisavam trabalhar com os dados dos maratonistas, alm disso a maratona de surf vem ganhando reconhecimento e sendo cada vez mais disputada. Os juzes esto felizes com o aumento do nmero de participantes, mas agora o programa quebra_galho no atende as novas necessidades que surgiram. Para ajudar os juzes o seu grupo deve elaborar um programa em pascal para facilitar a vida dos juzes na gerncia dos participantes da maratona. Agora eles querem uma soluo que armazene os dados sem perd-los toda vez que o computador for desligado. Para isso, seu grupo deve armazenar as informaes dos maratonistas em arquivo. O programa deve ser modularizado e oferecer as seguintes opes para os juzes: (1) Abrir um arquivo existente com as informaes dos maratonistas; - o juiz deve especificar o nome do arquivo a ser aberto; - caso no exista o arquivo, deve-se criar um novo arquivo em branco. (2) Cadastrar novos participantes; - o juiz deve especificar os dados de um novo maratonista. - caso o arquivo ainda no tenha sido especificado o programa deve chamar a opo 1 antes de executar o cadastro. (3) Exibir todas as informaes dos maratonistas; - este mdulo deve listar todas as informaes para todos os maratonistas, armazenadas em arquivo. (4) Ordenar os maratonistas por nota; - este mdulo deve ler todas as informaes do arquivo e armazen-las em um vetor (memria primria). Ordenar o vetor de acordo com a nota obtida pelo maratonista utilizando o algoritmo de ordenao do grupo. (5) Exibir os trs primeiros vencedores; - este mdulo deve exibir as trs primeiras posies do vetor j ordenado. (6) Realizar busca por nome; - o juiz deve especificar o nome do maratonista a ser buscado; - se o nome for encontrado: - este mdulo deve exibir todas as informaes referentes ao maratonista procurado e a sua classificao. A classificao a posio que ele for encontrado no vetor ordenado. - caso o nome no seja encontrado: - este mdulo deve informar ao juiz que o nome no foi encontrado. - OBS.: implementar a busca binria, o vetor deve estar ordenado quando este mdulo for ativado! (7) Sair do programa. - o programa deve ser finalizado quando o juiz escolher esta opo.

O Programa deve possuir as opes de (1) a (6) construdas de forma modularizada, alm disso o programa deve sempre perguntar ao juiz qual opo ele deseja realizar com a seguinte frase: Escolha uma das opes abaixo: (as opes devem ser listadas para que o juiz possa fazer a sua escolha). Os juzes decidiram que precisam armazenar as seguintes informaes para cada maratonista (lembre-se dos registros): - nome; - sobrenome; - idade; - cpf; - estado civil; - quantidade de ondas; - nota; - email;

4.2 Soluo
program Maratona_de_Surf; uses WinCrt, crt;

type dados = record //criei meu tipo para manipular as informaes nome:string; sobrenome:string; idade:integer; cpf:string[15]; estado_c:string; n_ondas:integer; nota: real; email: string; posi:integer; end; arquivo = File of dados; //um tipo do arquivo tipado do meu registro vetor=array[1..100] of dados; // um vetor do tipo do meu registro var arq:arquivo; op:char;

{--------------------------------------------------1-----------------------------------------------} procedure abrir; //abrir o arquivo. var nome_arq:string; Begin Write ('Digite o nome do arquivo: '); Readln (nome_arq); nome_arq:=nome_arq+'.dat'; Assign (arq, nome_arq); {faz o assinalamento} {$I-} Reset (arq); {tenta abrir o arquivo} If IOresult <> 0 then Rewrite (arq); {$I+} clrscr; end; {---------------------------------------------adicional---------------------------------------------} procedure erro(var aux:char); // para tratar de usuarios engraadinhos begin while(( aux<>'S')and (aux<>'N')) do begin writeln('Opcao Invalida'); writeln('Pressione S para sim e N para nao'); readln(aux); aux:=upcase(aux); end; clrscr; end; {---------------------------------------------2------------------------------------------------------} procedure novo_cad; var aux, conf:char; aux_no:string; cadr:dados; begin abrir; aux:='S';

while aux='S' do //repetir quantas vezes ele quiser begin repeat //Repetir at os dados estarem certos. write('Nome do participante: '); readln(aux_no); cadr.nome:=upcase(aux_no); //salva o nome todo em maisculo write('Sobrenome do participante: '); readln(aux_no); cadr.sobrenome:=upcase(aux_no); write('CPF do participante: '); readln(cadr.cpf); write('Estado Civil do participante: '); readln(cadr.estado_c); write('Quantidade de ondas: '); readln(cadr.n_ondas); write('Nota do participante: '); readln(cadr.nota); write('Email do Participante: '); readln(cadr.email); cadr.posi:=1;// para salvar a colocao do candidato aps a ordenao. writeln(); writeln('Os dados estao Corretos?'); writeln(); writeln('Pressione S Para confirmar e N para Alterar os Dados'); readln(conf); conf:=upcase(conf); if (( conf<>'S')and (conf<>'N')) then erro(conf); clrscr; writeln(); if conf='S' then {perguntar se os dados esto certos} begin seek(arq,filesize(arq)); {seek posiciona o vetor, e filesize para identificar quantos registros tem no arquivo, ento vai colocar no fim} write(arq,cadr); end else clrscr; writeln('Por favor, digite os dados do participante novamente.'); until conf='S'; {vai repetir at tudo est certo}

clrscr; writeln(); writeln('Deseja adicionar dados de outro participante? (s/n)'); readln(aux); aux:=upcase(aux); if (( aux<>'S')and (aux<>'N')) then erro(aux); clrscr; end; close(arq); exit; end; {-------------------------------------------------3------------------------------------------------} procedure leitura; var cadr:dados; aun:integer; begin abrir; writeln('Lista dos Participantes:'); aun:=1; while not(eof(arq)) do begin read(arq,cadr); {lendo o arquivo} writeln('Participante ', aun); writeln('Nome Completo: ',cadr.nome, #32,cadr.sobrenome ); writeln('CPF: ', cadr.cpf); writeln('Estado Civil: ', cadr.estado_c); writeln('Quantidade de ondas: ', cadr.n_ondas); writeln('Nota: ', cadr.nota:2:2); writeln('Email do Participante: ', cadr.email); inc(aun); writeln(); end; close(arq); writeln('Todos os participantes foram listados'); writeln('Precione [ENTER] para vontar ao Menu Principal'); readkey; clrscr;

exit;

end; {-------------------------------------------------4-----------------------------------------------} procedure merge(var v: vetor; ini,meio,fim: integer); var aux:vetor; i,j,k: integer; begin i := ini; j := meio + 1; k := ini; while ((i <= meio) and (j <= fim)) do begin if ((v[i].nota) > (v[j].nota)) then begin aux[k] := v[i]; inc(i); end else begin aux[k] := v[j]; inc(j); end; inc(k); end; while (i <= meio) do begin aux[k] := v[i]; inc(k); inc(i); end; while (j <= fim) do begin aux[k] := v[j]; inc(k); inc(j); end;

for k := ini to fim do v[k] := aux[k]; end; procedure mergesort(var v: vetor; i, f:integer); var m: integer; begin if i<f then begin m:=(i+f) div 2; mergesort(v, i, m); mergesort(v, m+1, f); merge(v,i,m, f); end; end; {prodecure principal da ordenao} procedure ordenar; var i, fim: integer; cadr:dados; vet_ord:vetor; begin i:=0; //ajudar na manipulao de dados. reset(arq); {passando pro vetor} while not(eof(arq)) do begin inc(i); // pra garantir que o vetor vai comear de 1 read(arq,cadr); vet_ord[i]:=cadr; end; close(arq); fim:=i; mergesort(vet_ord, 1, i); {chama o metodo de odenao} for i:=1 to fim do {salva a posio} vet_ord[i].posi:=i; Rewrite (arq); //apaga o arquivo para salvar ele ordenado.

i:=1; while i<fim+1 do begin cadr:=vet_ord[i]; write(arq,cadr); inc(i); end; close (arq); clrscr; exit; end; {--------------------------------------------------5----------------------------------------------------} procedure exibir; var i:integer; cadr:dados; begin ordenar; writeln('Listagem dos 3 primeiros colocados:'); reset(arq); for i:=1 to 3 do begin read(arq,cadr); {lendo o arquivo} writeln(i,' colocado(a): ',cadr.nome, #32,cadr.sobrenome ); end; close(arq); readkey; clrscr; writeln('Precione [ENTER] para voltar ao Menu Principal'); readkey; clrscr; exit; end; {------------------------------------------------6---------------------------------------------} procedure busca; var vetor_nom:vetor; i, j,k,ini, meio, fim:integer; cadr, aux:dados; opi:char;

achou:boolean; bus:string; begin ordenar; i:=0; //ajudar na manipulao de dados. reset(arq); {passando pro vetor} while not(eof(arq)) do begin inc(i); // pra garantir que o vetor vai comear de 1 read(arq,cadr); vetor_nom[i]:=cadr; end; close(arq); k:=i; //Ordenando os nomes for i:= k downto 2 do for j:=1 to i-1 do if (vetor_nom[j].nome > vetor_nom[j+1].nome) then begin aux := vetor_nom[j]; vetor_nom[j] := vetor_nom[j+1]; vetor_nom[j+1] := aux; end; writeln('Informe o nome do Participante que deseja buscar: '); readln (bus); //jogar upcase em todos nomes bus:=upcase(bus); opi:='S'; while opi='S' do begin ini:=1; fim:=k; achou:=false; repeat meio:=(ini+fim) div 2; if (bus=vetor_nom[meio].nome) then begin achou:= true;

ini:=fim+1; end else if (bus<vetor_nom[meio].nome) then fim:=meio-1 else ini:=meio+1; until (ini>fim); if achou=true then begin writeln ('O participante ', bus, ' est na ', vetor_nom[meio].posi, ' colocacao '); writeln('abaixo os dados do calango'); writeln('Nome Completo: ',vetor_nom[meio].nome, #32,vetor_nom[meio].sobrenome ); writeln('CPF: ', vetor_nom[meio].cpf); writeln('Estado Civil: ', vetor_nom[meio].estado_c); writeln('Quantidade de ondas: ', vetor_nom[meio].n_ondas); writeln('Nota: ', vetor_nom[meio].nota:2:2); writeln('Email do Participante: ', vetor_nom[meio].email); end else write ('Desculpe, o nome do participante nao consta em nosso banco de dados'); readkey; clrscr; write ('Deseja realizar uma nova busca? (s/n) ' ); readln(opi); opi:=upcase( opi); if opi='N' then break; writeln('Nome do Participante: '); readln (bus); bus:=upcase(bus); end; clrscr; writeln('Precione [ENTER] para voltar ao Menu Principal'); readkey; clrscr;

exit; end; procedure not_found(op:char); begin if(op<>'7') then begin writeln('Opcao invalida'); writeln('Precione [ENTER] Para voltar ao menu principal'); readkey; end; clrscr; end;

{programa principal} begin TextBackGround(CYAN); TextColor(WHITE); clrscr; op:='0'; while op<>'7' do begin Gotoxy(25,3); writeln ('CONCURSO DE SURF'); writeln (); writeln (); writeln ('Escolha uma das opcoes abaixo:'); writeln (); writeln ('(1) Abrir o Arquivo com as informacoes dos participaintes'); writeln ('(2) Cadastrar novos Participantes'); writeln ('(3) Exibir todas as informacoes.'); writeln ('(4) Organizar os participantes por nota.'); writeln ('(5) Exibir o top 3'); writeln ('(6) Realizar Busca'); writeln ('(7) Sair do Programa'); readln (op); clrscr;

case op of '1':abrir; '2':novo_cad; '3':leitura; '4':begin clrscr; ordenar; writeln('Participantes Ordenados'); writeln('Precione [ENTER] para retornar ao menu principal'); readkey; clrscr; end; '5': exibir; '6': busca; else not_found(op); end; end; readkey; end.

5 Referncias bibliogrficas
Merge Sort. Disponvel em http://pt.wikipedia.org/wiki/Merge_sort Acesso em: 01 de novembro. 2012. Estudo do algoritmo de ordenao Mergesort, Disponvel em http://www.slideshare.net/luizaguerra/estudo-do-algoritmo-de-ordenao-mergesort Acesso em: 01 de novembro. 2012.

Você também pode gostar