Aula 4
Compressão de Dados
Rodrigo da Cruz Fujioka fujiokabr@gmail.com
Estrutura de Dados 2
Objetivos-> Compressão de Dados
Apresentar técnicas para ordenação de
dados.
Introdução
• Um dos processos mais comuns de programação;
• Ordenar uma coleção de dados seguindo
3
• Ordenar uma coleção de dados seguindo
algum critério;
Introdução
• Elementos ordenados são muito utilizados no cotidiano.
Livros na biblioteca Lista telefônica;
Ordenação e busca
• Como visto anteriormente, algumas operações de busca “dependem” da ordenação dos dados;
5
Ordenação e busca
• A decisão de executar uma ordenação ou aplicar um método de busca deve levar em consideração algumas questões:
– Desempenho necessário;
– Massa de dados;
– Tempo para implementação;
– Freqüência de busca;
– Memória utilizada.
Ordenação e busca
• Ordenar primeiro e buscar depois?
– O custo das buscas sucessivas é maior que o custo da ordenação?
• Não ordenar?
7
• Não ordenar?
– A tabela é pequena e são feitas poucas buscas?
Ordenação e busca
• A decisão deve ser tomada pelo programador, levando em consideração circunstâncias individuais;
• O programador deve conhecer bem (vantagens e desvantagens) os algoritmos para tomar a decisão correta?
Métodos de ordenação
• Ordenação por Troca
• Ordenação por Inserção
• Ordenação por Seleção
• Ordenação por Distribuição de Chaves
• Ordenação por Distribuição de Chaves
– BucketSort
• Ordenação por Intercalação
– MergeSort
Ordenação por troca
Ordenação por troca
• Técnica básica: comparam-se dois elementos e trocam-se suas posições se o segundo elemento é menor do que o primeiro;
11
primeiro;
• Método da bolha (Bubble sort);
• Método Quick sort.
Bubble sort
• Princípio de funcionamento
– São feitas várias passagens na tabela;
– Quando dois elementos adjacentes estão fora de ordem, é feita a inversão e esses dois elementos são trocados de posição;
trocados de posição;
• Primeiro elemento é comparado com o segundo, o segundo com o terceiroK invertento quando necessário.
– Fim da comparação: quando o penúltimo é comparado com o último;
• Ao final, o maior elemento ficará posicionado na última posição.
– O processo continua até o que todo o vetor esteja ordenado.
Bubble sort
• Exemplo
25 48 37 12 57 86 33 22
25 48 37 12 57 86 33 22 (25x48)
25 48 37 12 57 86 33 22 (48x37) troca
48 12 (48x12) troca
13
25 37 48 12 57 86 33 22 (48x12) troca 25 37 12 48 57 86 33 22 (48x57)
25 37 12 48 57 86 33 22 (57x86)
25 37 12 48 57 86 33 22 (86x33) troca 25 37 12 48 57 33 86 22 (86x22) troca
25 37 12 48 57 33 22 86
Final do 1º “ciclo”: o maior elemento (86) está na posição final
Bubble sort
• Vantagem
– Simplicidade do algoritmo
• Desvantagem
– Lentidão
• Indicação de uso
• Indicação de uso
– Pequena coleção, coleção “quase ordenada” e demonstração didática.
• Observação
– Para evitar que o processamento continue mesmo depois do vetor estar ordenado pode-se utilizar uma variável que indique a ordenação.
Bubble sort
• void ordenacaoBolha(int v[]){
• int i, temp, ordenado=0;
• while(!ordenado){
• ordenado=1; // Supõe ordenamento
• for(i=0; i<TAM-1; i++){
15
• if(v[i] > v[i+1]){ // Compara adjacentes
• temp = v[i]; // Troca adjacentes
• v[i] = v[i+1]; // Troca adjacentes
• v[i+1] = temp; // Troca adjacentes
• ordenado=0; // Não está ordenado
• }
• }
• }
• }
Quick Sort
• Ordenação rápida!
• Baseado no princípio “dividir para conquistar”
– Resolução de um problema maior quebrando-o em dois ou mais problemas menores
• Princípio de funcionamento
• Princípio de funcionamento
– Considere a sequencia V={V1,V2,V3,K,V8}
– Escolher um elemento específico “p” dentro do vetor (chamado de “pivô”)
• Podemos escolher como pivô o primeiro elemento do vetor e posicioná-lo em sua posição correta na primeira passada.
• Princípio de funcionamento (cont.)
– Observe:
12 25 37 48 57 86 33 92
• Todos os elementos depois do pivô são maiores que ele!
• Quick Sort
17
que ele!
• Todos os elementos antes do pivô são menores que ele!
– Agora vamos particionar o vetor em dois subconjuntos (a partir do pivô).
12 (indice 0-0)
37 48 57 86 33 92 (indices de 2-7)
Quick Sort
• Princípio de funcionamento (cont.)
– Agora nós repetimos o mesmo procedimento para cada vetor
• Achar o pivô e coloca-lo no lugar correto
• Fazer a troca do pivô
• Fazer a troca do pivô
– Observação:
• O primeiro vetor (0-0), para apenas 1 elemento, já se encontra ordenado.
• O segundo vetor(2-7), vai ser ordenado de forma semelhante
– Forma de implementação:
Geralmente recursiva!!!
Quick Sort
• Vantagem
– Muito rápido, em média
• Desvantagem
– Se a coleção estiver quase ordenada, seu
19
– Se a coleção estiver quase ordenada, seu processo é lento
• Indicação de uso
– Situações práticas onde a coleção não esteja frequentemente “quase” ordenada.
Quick Sort
void quicksort(int tam, int *v) {
/* se o vetor possui 1 ou menos elementos, nao tem sentido ordena-lo */
if (tam <= 1) return;
else {
/* pivo escolhido foi o primeiro elemento */
int pivo = v[0];
/* indice que sobe de forma crescente */
int a = 1;
/* indice que desce de forma decrescente */
int b = tam - 1; /* Recebe o ultimo indice */
/* Vamos determinar a posicao correta do pivo */
do{
/* Deslocando o indice para a direita*/
while( a < tam && v[a] <= pivo ) a++;
/* Deslocando o indice do final para a esquerda */
while( v[b] > pivo ) b--;
21 b--;
/* Se o indice "a" for menor que "b", realizamos a troca */
if ( a < b ) {
int temp = v[a];
v[a] = v[b];
v[b] = temp;
a++;
b--;
}
} while (a <= b);
/* Ja foi encontrado o lugar do pivo.
Agora vamos troca-lo com o elemento que se encontra no indice b*/
v[0] = v[b];
v[b] = pivo;
/* Vamos ordenar os subvetores restantes */
quicksort(b, v); /* Ordenando o lado esquerdo do pivo */
quicksort(tam-a, &v[a] ); /* Agora ordena o lado direito */
} }
Exercício
• Modifique o programa criado no exercício anterior, substituindo o algoritmo de ordenação Bubble Sort pelo algoritmo Quick Sort.
Quick Sort.
• Verifique se há mudança significativa no
tempo gasto para ordenação.
Ordenação por seleção
Métodos de ordenação
• Ordenação por Troca
• Ordenação por Inserção
• Ordenação por Seleção
• Ordenação por Distribuição de Chaves
• Ordenação por Distribuição de Chaves
– BucketSort
• Ordenação por Intercalação
– MergeSort
Ordenação por Seleção
• Princípio de funcionamento
– Selecionar o menor item do vetor. Em seguida, troque-o com o item que está na primeira posição do vetor
– Repetir o procedimento para os n-1 elementos restantes
25 48 37 12 57 86 33 92
25
25 48 37 12 57 86 33 92 12 48 37 25 57 86 33 92 12 25 37 48 57 86 33 92 12 25 33 48 57 86 37 92 12 25 33 37 57 86 48 92 12 25 33 37 48 86 57 92
12 25 33 37 48 57 86 92 (Ordenado)
Ordenação por Seleção
• Vantagem
– Simplicidade do algoritmo
– Bom comportamento quanto ao número de movimentações
• Desvantagem
– Se o vetor estiver ordenado, haverá troca de qualquer forma (não ajuda em nada!)
• Indicação de uso
– Coleções com itens de dados compostos e grandes (pouca movimentação).
• void ordenacaoSelecao(int v[], int tam){
• int i=0, temp=0, ini=0, posMenor=0;
• while(ini<tam){
• posMenor=ini;
• for(i=ini; i<tam; i++){
• if(v[i] < v[posMenor]){
• posMenor = i;
• }
27
• }
• }
• temp = v[ini];
• v[ini] = v[posMenor];
• v[posMenor] = temp;
• ini++;
• }
• }
Ordenação por inserção
Métodos de ordenação
• Ordenação por Troca
• Ordenação por Inserção
• Ordenação por Seleção
• Ordenação por Distribuição de Chaves
• Ordenação por Distribuição de Chaves
– BucketSort
• Ordenação por Intercalação
– MergeSort
Inserção simples
• Técnica básica
– Semelhante ao ordenamento de cartas de baralho na mão de um jogador.
– A mão esquerda começa "vazia" e a mão – A mão esquerda começa "vazia" e a mão direita insere uma "carta" de cada vez na posição correta.
– Ao final, quando todas as "cartas" foram inseridas, elas já estarão ordenadas
Inserção simples
• Algoritmo
– Dividi-se o vetor em dois segmentos: o primeiro com os elementos já ordenado e o seguinte com o restante dos elementos ainda não ordenados.
– O primeiro elemento é colocado no primeiro
31
– O primeiro elemento é colocado no primeiro segmento;
– Retira-se o primeiro elemento do segmento desordenado e insere-se no segmento ordenado em sua posição correta;
– Repete-se o processo para os demais elementos do vetor.
Inserção simples
• Vantagens:
– Simplicidade
• Desvantagens:
– Lentidão – Lentidão
• Indicações:
– Tabelas pequenas e quase ordenadas
Inserção simples
• void insertionSort( int vetor[], int num){
• int i,j,key;
• for (j=1; j < num; j++){
• key = vetor[j];
33
key = vetor[j];
• i = j - 1;
• while (( i >= 0 ) && ( vetor[i] > key )){
• vetor[i+1] = vetor[i];
• i--;
• }
• vetor[i+1] = key;
• }
• }
Shell Sort
• Utiliza-se uma série de espaçamentos (incrementos) decrescentes e utiliza-se ordenação por inserção simples para cada espaçamento entre elementos
• Incrementos originais de Shell: h1 = n/2, hk = hk+1/2
• Incrementos originais de Shell: h1 = n/2, hk = hk+1/2
• A ordenação encerra quando o espaçamento de 1 é usado
• Exemplo: se o espaçamento 5 estiver sendo utilizado, são examinados os elementos de ordem 1 e 6, depois 2 e 7, 3 e 8, etc.
Shell Sort
• Vantagens:
– Razoavelmente rápido
• Desvantagens:
– Eficiência depende da escolha correta dos
35
– Eficiência depende da escolha correta dos incrementos
• Indicações:
– Tabelas pequenas e médias
Shell Sort
• void Shell(int v[], int nelem){
• int salto,k,i,j,x;
• for (salto=nelem/2; salto>0; salto /= 2){
• for (i=salto; i<nelem; i++){
• x=v[i];
• j=i-salto;
• j=i-salto;
• while ((x<v[j]) && (j>=0)) {
• v[j+salto]=v[j];
• j=j-salto;
• }
• v[j+salto]=x;
• }
• }
• }
Exercício
• Inclua o método Shellsort e verifique seu desempenho em relação aos demais métodos.
37
Métodos de ordenação
• Ordenação por Troca
• Ordenação por Inserção
• Ordenação por Seleção
• Ordenação por Distribuição de Chaves
• Ordenação por Distribuição de Chaves
– BucketSort
• Ordenação por Intercalação
– MergeSort
Ordenação por intercalação
Merge Sort
• Aleatoriamente, divide-se a tabela original em duas tabelas
• Recursivamente, ordenam-se as duas tabelas e intercalam-se as duas tabelas ordenadas
• Vantagens:
40
• Vantagens:
– No pior caso, é mais rápido do que Quicksort
• Desvantagens:
– Uso de memória adicional
• Indicações:
– Ordenação de arquivos (ordenação externa)
Vide:http://www.cse.iitk.ac.in/users/dsrkg/cs210/applets/sortingII/merg eSort/mergeSort.html
Merge Sort
41
Merge Sort
Merge Sort
43
Merge Sort
Exercício
• Inclua o método Mergesort e verifique seu desempenho em relação aos demais métodos.
45
Ordenação por Distribuição de chaves
de chaves
Bucket Sort
• Assume-se uma distribuição uniforme das chaves
• Divide-se o intervalo de chaves em n buckets, distribuindo-se as chaves entre eles.
47
distribuindo-se as chaves entre eles.
• Ordena-se as chaves em cada bucket, retornando as chaves na ordem dos buckets
• Vantagens:
– No caso médio é linear
Bucket Sort
Bucket Sort
49