You are on page 1of 8

Introdução

• Um dos processos mais comuns de


programação;
Estrutura de dados II
• Ordenar uma coleção de dados seguindo
Prof. Rodrigo Lobo algum critério;
• Elementos ordenados são muito utilizados
no cotidiano.
Ordenação de dados – Lista telefônica;
– Livros na biblioteca.

Ordenação e busca Ordenação e busca


• Como visto anteriormente, algumas operações • Ordenar primeiro e buscar depois?
de busca “dependem” da ordenação dos dados; – O custo das buscas sucessivas é maior que o custo
da ordenação?
• A decisão de executar uma ordenação ou • Não ordenar?
aplicar um método de busca deve levar em – A tabela é pequena e são feitas poucas buscas?
consideração algumas questões: • A decisão deve ser tomada pelo programador,
– Desempenho necessário; levando em consideração circunstâncias
individuais;
– Massa de dados;
• O programador deve conhecer bem (vantagens
– Tempo para implementação; e desvantagens) os algoritmos para tomar a
– Freqüência de busca; decisão correta.
– Memória utilizada.
3 4

Ordenação por troca


• Técnica básica: comparam-se dois
elementos e trocam-se suas posições se o
Ordenação por troca segundo elemento é menor do que o
primeiro;
• Método da bolha (Bubble sort);
• Método Quick sort.

1
Bubble sort Bubble sort
• Princípio de funcionamento • Exemplo
– São feitas várias passagens na tabela; 25 48 37 12 57 86 33 22
– Quando dois elementos adjacentes estão fora de
ordem, é feita a inversão e esses dois elementos são 25 48 37 12 57 86 33 22 (25x48)
trocados de posição; 25 48 37 12 57 86 33 22 (48x37) troca
• Primeiro elemento é comparado com o segundo, o segundo 25 37 48 12 57 86 33 22 (48x12) troca
com o terceiro… invertento quando necessário. 25 37 12 48 57 86 33 22 (48x57)
– Fim da comparação: quando o penúltimo é 25 37 12 48 57 86 33 22 (57x86)
comparado com o último; 25 37 12 48 57 86 33 22 (86x33) troca
• Ao final, o maior elemento ficará posicionado na última 25 37 12 48 57 33 86 22 (86x22) troca
posição. 25 37 12 48 57 33 22 86
– O processo continua até o que todo o vetor esteja Final do 1º “ciclo”: o maior elemento (86) está na posição final
ordenado. 7 8

Bubble sort Bubble sort


• Vantagem void ordenacaoBolha(int v[]){
– Simplicidade do algoritmo int i, temp, ordenado=0;
• Desvantagem while(!ordenado){
ordenado=1; // Supõe ordenamento
– Lentidão
for(i=0; i<TAM-1; i++){
• Indicação de uso if(v[i] > v[i+1]){ // Compara adjacentes
– Pequena coleção, coleção “quase ordenada” e temp = v[i]; // Troca adjacentes
demonstração didática. v[i] = v[i+1]; // Troca adjacentes
v[i+1] = temp; // Troca adjacentes
• Observação ordenado=0; // Não está ordenado
– Para evitar que o processamento continue mesmo }
depois do vetor estar ordenado pode-se utilizar uma }
variável que indique a ordenação. }
9 10
}

Exercício Quick Sort


• Ordenação rápida!
• Demonstrar o tempo necessário para
realizar uma operação de busca em um • Baseado no princípio “dividir para conquistar”
vetor de 10.000 posições, levando em – Resolução de um problema maior quebrando-o em
dois ou mais problemas menores
consideração as seguintes situações:
• Princípio de funcionamento
– Vetor desordenado, busca seqüencial;
– Considere a sequencia V={V1,V2,V3,…,V8}
– Vetor ordenado (Bubble Sort), busca binária.
– Escolher um elemento específico “p” dentro do vetor
• Nesta situação deve-se levar em consideração o
(chamado de “pivô”)
tempo da ordenação + o tempo da busca.
• Podemos escolher como pivô o primeiro elemento do vetor
– Verificar o tempo para buscar 1000, 10000, e posicioná-lo em sua posição correta na primeira
20000 elementos. passada.

11 12

2
Quick Sort Quick Sort
• Princípio de funcionamento (cont.) • Princípio de funcionamento (cont.)
– Identificar a posição correta do pivô – Continua a busca
• Comparar os elementos v[1],v[2],… até encontrar um • Para cima a partir de v[a+1] e para baixo a partir de v[b-1]
elemento v[ a ] > pivo • O processo termina quando b cruzar com a ( b<a)
25 48 37 12 57 86 33 92 25 12 37 48 57 86 33 92
a a=1 a b a=b=2
• A partir do final do vetor, compara os elementos v[tam-1], 25 12 37 48 57 86 33 92
v[tam-2],… até encontrar um elemento v[b] <= pivo
a b a=2, b = 1 (b<a)
25 48 37 12 57 86 33 92
• Agora a posição do pivô já está definida: trocar
a b a=1, b=3 v[0] por v[b]
• Neste ponto, troca-se v[a] com v[b] 12 25 37 48 57 86 33 92
25 12 37 48 57 86 33 92 13 14

Quick Sort Quick Sort


• Princípio de funcionamento (cont.) • Princípio de funcionamento (cont.)
– Observe: – Agora nós repetimos o mesmo procedimento
12 25 37 48 57 86 33 92 para cada vetor
• Todos os elementos depois do pivô são maiores • Achar o pivô e coloca-lo no lugar correto
que ele! • Fazer a troca do pivô
• Todos os elementos antes do pivô são menores – Observação:
que ele! • O primeiro vetor (0-0), para apenas 1 elemento, já
– Agora vamos particionar o vetor em dois se encontra ordenado.
subconjuntos (a partir do pivô). • O segundo vetor(2-7), vai ser ordenado de forma
semelhante
12 (indice 0-0)
– Forma de implementação:
37 48 57 86 33 92 (indices de 2-7)
15
Geralmente recursiva!!! 16

void quicksort(int tam, int *v) {


/* se o vetor possui 1 ou menos elementos, nao tem sentido ordena-lo */
if (tam <= 1)
return;

Quick Sort else {


/* pivo escolhido foi o primeiro elemento */
int pivo = v[0];
/* indice que sobe de forma crescente */
int a = 1;
• Vantagem /* indice que desce de forma decrescente */
int b = tam - 1; /* Recebe o ultimo indice */
/* Vamos determinar a posicao correta do pivo */
– Muito rápido, em média do{
/* Deslocando o indice para a direita*/
while( a < tam && v[a] <= pivo )
• Desvantagem a++;
/* Deslocando o indice do final para a esquerda */
while( v[b] > pivo )
– Se a coleção estiver quase ordenada, seu b--;
/* Se o indice "a" for menor que "b", realizamos a troca */
processo é lento if ( a < b ) {
int temp = v[a];
v[a] = v[b];

• Indicação de uso v[b] = temp;


a++;
b--;
– Situações práticas onde a coleção não esteja }
} while (a <= b);
/* Ja foi encontrado o lugar do pivo.
frequentemente “quase” ordenada. 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 */
17 } 18
}

3
Exercício
• Modifique o programa criado no exercício
anterior, substituindo o algoritmo de
ordenação Bubble Sort pelo algoritmo Ordenação por seleção
Quick Sort.
• Verifique se há mudança significativa no
tempo gasto para ordenação.

19

Ordenação por Seleção Ordenação por Seleção


• Princípio de funcionamento • Vantagem
– Selecionar o menor item do vetor. Em seguida, troque-o com o – Simplicidade do algoritmo
item que está na primeira posição do vetor
– Bom comportamento quanto ao número de
– Repetir o procedimento para os n-1 elementos restantes movimentações
• Desvantagem
25 48 37 12 57 86 33 92
– Se o vetor estiver ordenado, haverá troca de qualquer
12 48 37 25 57 86 33 92 forma (não ajuda em nada!)
12 25 37 48 57 86 33 92
12 25 33 48 57 86 37 92
• Indicação de uso
12 25 33 37 57 86 48 92 – Coleções com itens de dados compostos e grandes
12 25 33 37 48 86 57 92 (pouca movimentação).
12 25 33 37 48 57 86 92 (Ordenado)
21 22

void ordenacaoSelecao(int v[], int tam){


int i=0, temp=0, ini=0, posMenor=0;
Exercício
while(ini<tam){
posMenor=ini; • Dê continuidade aos exercícios anteriores (verificação
for(i=ini; i<tam; i++){ de desempenho dos métodos de ordenação), incluindo
if(v[i] < v[posMenor]){ ao programa já desenvolvido o algoritmo de ordenação
por seleção (apresentado na última aula). O programa
posMenor = i; deverá comparar os métodos de ordenação Bubblesort,
} Suicksort e Seleção e apresentar o tempo gasto para
} cada ordenação (verifique o desempenho para vetores
temp = v[ini]; com 5.000, 10.000 e 20.000 elementos).
v[ini] = v[posMenor]; • O algoritmo de ordenação apresentado na última aula
v[posMenor] = temp; não utiliza recursividade em sua solução. Implemente a
ini++; versão recursiva do algoritmo e verifique seu
} desempenho em relação à versão não recursiva.
}
23 24

4
Ordenação por Árvore Binária Ordenação por Árvore Binária
• Constrói-se uma árvore binária de busca • Vantagens
usando os elementos da tabela. – Quando a árvore já existe.
• Faz-se um caminhamento em in-ordem • Desvantagens
copiando os elementos de volta na tabela – Requer código demais na implementação
original na ordem em que estes são – Uso de memória adicional
encontrados. • Indicações
– Tabelas não muito grandes

25 26

Exercício
• Inclua o método de Ordenação por Árvore
Binária e verifique seu desempenho em
relação aos demais métodos. Ordenação por inserção

27

Inserção simples Inserção simples


• Técnica básica • Algoritmo
– Semelhante ao ordenamento de cartas de – Dividi-se o vetor em dois segmentos: o primeiro com
os elementos já ordenado e o seguinte com o
baralho na mão de um jogador.
restante dos elementos ainda não ordenados.
– A mão esquerda começa "vazia" e a mão – O primeiro elemento é colocado no primeiro
direita insere uma "carta" de cada vez na segmento;
posição correta. – Retira-se o primeiro elemento do segmento
– Ao final, quando todas as "cartas" foram desordenado e insere-se no segmento ordenado em
sua posição correta;
inseridas, elas já estarão ordenadas
– Repete-se o processo para os demais elementos do
vetor.
29 30

5
Inserção simples Inserção simples
void insertionSort( int vetor[], int num){
• Vantagens:
int i,j,key;
– Simplicidade
• Desvantagens: for (j=1; j < num; j++){
key = vetor[j];
– Lentidão i = j - 1;
while (( i >= 0 ) && ( vetor[i] > key )){
• Indicações: vetor[i+1] = vetor[i];
i--;
– Tabelas pequenas e quase ordenadas }
vetor[i+1] = key;
}
}

31 32

Exercício Shell Sort


• Inclua o método de Inserção Simples e • Utiliza-se uma série de espaçamentos
(incrementos) decrescentes e utiliza-se
verifique seu desempenho em relação aos ordenação por inserção simples para cada
demais métodos. espaçamento entre elementos
• 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.

33 34

Shell Sort Shell Sort


void Shell(int v[], int nelem){
• Vantagens: int salto,k,i,j,x;
– Razoavelmente rápido for (salto=nelem/2; salto>0; salto /= 2){
for (i=salto; i<nelem; i++){
• Desvantagens: x=v[i];
– Eficiência depende da escolha correta dos j=i-salto;

incrementos while ((x<v[j]) && (j>=0)) {


v[j+salto]=v[j];
• Indicações: j=j-salto;
}
– Tabelas pequenas e médias v[j+salto]=x;
}
}
}
35 36

6
Exercício
• Inclua o método Shellsort e verifique seu
desempenho em relação aos demais
métodos. Ordenação por intercalação

37

Merge Sort 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:
– No pior caso, é mais rápido do que Quicksort
• Desvantagens:
– Uso de memória adicional
• Indicações:
– Ordenação de arquivos (ordenação externa)

39 40

Merge Sort Merge Sort

41 42

7
Exercício
• Inclua o método Mergesort e verifique seu
desempenho em relação aos demais
métodos.

43

You might also like