mergesort - FT

Propaganda
Universidade Estadual de Campinas
Faculdade de Tecnologia
ST 364 – Estruturas de Dados
GRUPO 04
MERGESORT
Alunos:
André Pereira Giacon
Dandara Contieri Folis
Diego Narciso Hernandes
Fernanda Cristina Spadotim
Ordenação
Ordenação é o ato de se colocar os elementos de uma sequência de informações, ou
dados, em uma relação de ordem predefinida. O termo técnico em inglês para
ordenação é sorting, cuja tradução literal é "classificação".
Algumas ordens são facilmente definidas. Por exemplo, a ordem numérica, ou a ordem
alfabética – crescentes ou decrescentes. Contudo, existem ordens, especialmente de
dados compostos, que podem ser não triviais de se estabelecer.
Um algoritmo que ordena um conjunto, geralmente representada num vetor, é
chamado de algoritmo de ordenação.
Algoritmo de ordenação: existem várias razões para se ordenar uma sequência.
Uma delas é a possibilidade de acessar seus dados de modo mais eficiente.
Entre os mais importantes, podemos citar bubble sort (ou ordenação por flutuação),
heap sort (ou ordenação por heap), insertion sort (ou ordenação por inserção), merge
sort (ou ordenação por mistura) e o quicksort. Existem diversos outros, que o aluno
pode com dedicação pesquisar por si.
Métodos de ordenação de vetores
Métodos simples
 Insertion sort
 Selection sort
 Bubble sort
Métodos sofisticados
 Quick sort
 Merge sort
 Heapsort
 Shell sort
 Radix sort
 Gnome sort
 Count sort
 Bogosort
 Bucket sort
 Cocktail sort
Métodos de pesquisa
 Pesquisa binária
 Busca linear
 BogoBusca
Introdução ao MergeSort
História
Ainda existe uma discussão sobre o assunto, mas apareceram evidências de que o
algoritmo foi proposto por John Von Neumann em 1945. Essa discussão existe, pois
estudar as várias contribuições que ele fez é, ao mesmo tempo, complexa e
fascinante. Essa complexidade devesse em parte a existência de muitas fontes de
informação, algumas pouco acessíveis, outras discordantes entre si ou polêmicas.
A atribuição a ele veio de Knuth, que argumentou no seu livro ‘Arte de Programação
Computacional: Ordenando e Procurando’ que Von Neumann foi o primeiro a
descrever a idéia.
Significado do MergeSort
Nós vimos que o Quicksort é baseado em selecionar um elemento e dividir a lista em
duas metades e então, ordenar-las separadamente. Há também um processo
complementar o qual é chamado de junção. Dando 2 listas as quais estão ordenadas,
combinando-as em uma lista ordenada maior.
O processo de Seleção e junção são complementares porque:
Seleção: divide a lista em 2 outras independentes.
Junção: une 2 listas independentes em uma lista maior ordenada. Isso insinua que o
Mergesort consiste em duas chamadas recursivas e um processo de junção.
Então, Mergesort é um algoritmo recursivo, que é implementado dividindo uma
sequência original em pares de dados, ordena-as e depois as agrupa em sequências
de quatro elementos, e assim por diante, até ter toda a sequência dividida em apenas
duas partes.
Assim, sua idéia básica é que é muito fácil criar uma sequência ordenada a partir de
duas outras também ordenadas.
Classificação
- Ordenação por partição
O Mergesort é classificado como ordenação por partição, que parte do princípio de
"dividir para conquistar". Este princípio é uma técnica 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 técnica realiza-se em três fases:
Divisão: o problema maior é dividido em problemas menores e os problemas menores
obtidos são novamente divididos sucessivamente de maneira recursiva.
Conquista: o resultado do problema é calculado quando o problema é pequeno o
suficiente.
Combinação: os resultados dos problemas menores são combinados até que seja
obtida a solução do problema maior. Algoritmos que utilizam o método de partição são
caracterizados por serem os mais rápidos dentre os outros algoritmos pelo fato de sua
complexidade ser, na maioria das situações, O(nlogn). Os dois representantes mais
ilustres desta classe são o quicksort e o mergesort.
- Não é um método in-place
Em ciência da computação, um algoritmo in-place é um algoritmo que transforma a
entrada de informação usando Estrutura de Dados com uma pequena e constante
quantidade de espaço de memória extra. A entrada de informação geralmente é
sobrescrita por uma saída de dados como o algoritmo executa. Um algoritmo que não
é in-place, no caso, do Merge Sort, é chamado de out-of-place.
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 estável na maioria de suas implementações, onde estas podem ser iterativas
ou recursivas. Sua desvantagem é o fato de utilizar uma estrutura auxiliar, ocupando o
dobro de memória.
É interessante destacar suas características em cima do paradigma de "divisão para
conquista":
Dividir: se a seqüência tiver mais de um elemento, divida em duas partes.
Conquistar: ordene cada subseqüência em separado usando mergesort.
Combinar: junte as duas subseqüências em uma seqüência ordenada.
A operação de fusão merge, do mergesort, é muito utilizada na busca online, aonde os
dados chegam de blocos em blocos, são ordenados por qualquer método e depois
fundidos pela mesma. No entanto, esta abordagem pode demandar muito tempo e
espaço de armazenamento se os blocos recebidos forem pequenos em comparação
com os dados ordenados.
Figura 1: Funcionamento do algoritmo mergesort.
Funcionamento do MergeSort
Pseudocódigo
Variáveis:







n = número de elementos
X = vetor para ordenação
T = auxiliar na comparação
A,B = vetores auxiliares
m = auxiliar na divisão do vetor
i, j = auxiliares na intercalação e divisão
k = auxiliar na intercalação
Complexidade
Primeiramente vamos definir o que é melhor, médio e pior caso para o MergeSort.
Melhor Caso – nunca é necessário trocar após comparações.
Médio Caso – há necessidade de haver troca após comparações.
Pior Caso – sempre é necessário trocar após comparações.
Para o MergeSort não tem tanta importância se o vetor está no melhor, médio 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
Médio 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 situação se
encontra o vetor, ele sempre irá dividir e intercalar.
Na prática, é difícil (senão impossível) prever com rigor o tempo de execução 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.
Desta maneira, nós não vamos apresentar aqui como é o calculo da análise de
complexidade do MergeSort.
Testes:
Teste realizado por um aluno na Universidade Federal de Ouro Preto.
Computador com as seguintes configurações:
- Processador Pentium D 2.8 Ghz FSB 800 Mhz;
- 1 GB de memória ram DDR 533 Mhz;
- Placa Mãe Asus P5ND2;
- Sistema Operacional Microsoft Windows XP Service Pack 3.
- Linguagem C++
- Software: Microsoft Visual Studio Express 2008.
Métodos de ordenação:
1. BubbleSort
2. QuickSort
3. MergeSort
Tipo de vetor: Vetor aleatório – Caso médio
Quantidade de Comparações
100
1.000
10.000
100.000
BubbleSort
4.950
499.500
49.995.000
4.999.950.000
QuickSort
997
12.852
181.203
2.114.943
MergeSort
558
8.744
123.685
1.566.749
Quantidade de Movimentos
100
1.000
10.000
100.000
BubbleSort
2.628
242.827
25.160.491
2.499.136.980
QuickSort
570
8.136
103.575
1.310.586
MergeSort
1376
19968
272640
3385984
Tempo de execução (s)
100
1.000
10.000
100.000
BubbleSort
0,00007
0,0081
0,8587
114,8400
QuickSort
0,00003
0,0004
0,0049
0,0844
MergeSort
0,00015
0,0016
0,0194
0,2316
Vantagens e Desvantagens
Vantagens:
- Útil para ordenação externa;
- Pior caso: O(n log2 n)
- Aplicações com restrição de tempo
- Fácil implementação
Desvantagens:
- Utiliza memória auxiliar
- Alto consumo de memória
Outras Informações
•
Eficiente para ordenar listas:
Na literatura da ciência da computação está cheio de algoritmos de ordenação, e
todas elas parecem funcionar em vetores.





Bubblesort, Insertion Sort and Selection Sort são ruins;
Shellsort é melhor, mas nada perto do limite teórico O(n log n);
Quicksort é ótimo quando funciona, mas não confiável;
Mergesort é confiável, mas requer O(n) espaço auxiliar;
Heapsort is reliably good, but unstable, and also about a factor of 4 slower than
Quicksort's best case.
Mas e se quisermos ordenar algo mais do que um vetor? Árvores binárias já são todas
pré-ordenadas, mas e as listas ligadas?
Para isso, temos o MergeSort que funciona ainda melhor em listas ligadas em
comparação que ele faz em matrizes. Isso evita a necessidade de um espaço auxiliar,
e se torna um simples e confiável algoritmo de ordenação. E ainda como bônus, é
muito estável.
Descrição do Algoritmo
MergeSort leva a lista de entrada e a trata como uma coleção de pequenas listas
ordenadas. Faz log N, passa ao longo da lista, e em cada passagem, combina cada
par adjacente de pequenas listas ordenadas em uma lista maior ordenada. Quando
uma passagem só precisa fazer isso uma vez, toda lista de saída deve ser ordenada.
Mais detalhadamente. Em cada passagem, estamos fazendo a fusão de listas de
tamanho K em listas de tamanho 2K. (Inicialmente, K for igual a 1.) Assim, começamos
por apontar um ponteiro temporário p no topo da lista, e também a preparar uma lista
vazia L que vamos acrescentar elementos ao final enquanto terminamos de lidar com
eles.
Assim um passe de como este é realizado e é só preciso fazer uma mescla, o
algoritmo termina, e da lista de saída L é ordenado. Caso contrário, o valor de K dobra,
e voltar ao começo.
Este procedimento utiliza apenas ligações para a frente, por isso não precisa de uma
lista duplamente ligada. Se ele tem que lidar com uma lista duplamente ligada, o único
lugar onde importa é quando adicionar outro item de L.
Lidar com uma lista ligada circular também é possível. Você apenas tem que ter
cuidado ao pisar ao longo da lista. Para lidar com a ambigüidade entre p == topo
significa que você acabou de tirar o pé do final da lista, e p == topo significa que você
apenas começou, eu costumo usar uma forma alternativa de a etapa "exploração: em
primeiro lugar p passo para o elemento sucessor e, em seguida, redefini-lo para null se
esse passo a que se tornasse igual à cabeça da lista.
(Você pode rapidamente de-circularise uma lista ligada, encontrando o segundo
elemento, e, em seguida, quebrar o link para ela do primeiro, mas este se move toda a
lista por um round antes do processo de triagem. Isso não importa - estamos prestes a
classificar a lista, depois de tudo - exceto que ela faz com que a sorte instável).
•
MergeSort possui ordenação estável
Um algoritmo de ordenação diz-se estável se preserva a ordem de registros de chaves
iguais. Isto é, se tais registros aparecem na sequência ordenada na mesma ordem em
que estão na sequência inicial.
Esta propriedade é útil apenas quando há dados associados às chaves de ordenação.
Exemplo
Por exemplo, um algoritmo estável ordenando a sequência de números (chaves) com
letras associadas (registros):
3[a], 2[b], 2[c], 1[d]
obrigatoriamente retornará:
1[d], 2[b], 2[c], 3[a]
enquanto algoritmos instáveis sujeitam os elementos associados aos objetos a serem
ordenados a mudanças:
1[d], 2[c], 2[b], 3[a]

Implementação
Certos algoritmos são estáveis a partir de sua concepção original, como o MergeSort.
Porém, é possível implementar a estabilidade artificialmente em certos algoritmos. Por
exemplo, numa comparação de dois objetos de mesmo valor pode aplicar-se uma
comparação adicional para verificar se a ordem original dos registros associados foi
mantida. Neste caso, a implementação de estabilidade requer um custo adicional de
eficiência.
Algoritmos estáveis
Alguns algoritmos de ordenação estáveis:






Bubble sort
Cocktail sort
Insertion sort
Merge sort
Bucket sort
Counting sort
Algoritmos instáveis
Alguns algoritmos de ordenação instáveis:




Quicksort
Heapsort
Selection sort
Shell sort
Referencias Bibliográficas
BOSCARIOL, LEANDRO A.; GAMEIRO, LUCAS B.; ARRUDA, RODRIGO L. S.
Algoritmos
de
Ordenação.
Disponível
em:
<
http://www2.dc.uel.br/~rlarruda/trab/algoritmos-ordenacao.pdf>. Acesso em: 01 de jun.
de 2010.
CAPPABIANCO, FÁBIO AUGUSTO MENOCCI. MC102, Aula 19 – MergeSort.
Disponível em: <http://www.ic.unicamp.br/~fabioamc/mc102b/aulas/aula20.pdf >.
Acesso em: 03 de jun. de 2010.
JÚNIOR, ANTONIO CARLOS DE NAZARÉ. Algoritmos e Estruturas de Dados Métodos
de
ordenação
Interna.
Disponível
em:
<
http://www.decom.ufop.br/menotti/aedI082/tps/tp3-sol1.pdf>. Acesso em: 30 de mai. de
2010.
Download