introdução à programação 2006/07 - ipsltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf ·...

43
Introdução à Programação Pesquisa e ordenação

Upload: others

Post on 23-Jul-2020

21 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação

Pesquisa e ordenação

Page 2: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa

Dado um vector de n elementos, pretende-se saber se um determinado valor esta presente nesse vector .Para efeitos práticos, vamos supor que esse vector implementado como sendo um vector de n elementos inteiros: vector[0]..vector[n-1].

Page 3: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Tipos de pesquisa

Pesquisa sequencialPesquisa binária (dicotómica)

Page 4: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa sequencial

Uma solução possível é percorrer o vector desde a primeira posição até a última. Para cada posição i, comparamos vector[i] com valor.

Se forem iguais dizemos que valor existe.Se chegarmos ao índice m do vector sem sucesso dizemos que valor não existe.

Page 5: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa sequencial

1º passo | inicialização

i = 0;encontrado = 0; /*falso*/

Page 6: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa sequencial

2o passo | pesquisa

while (i < TAMANHO && !encontrado) {i{ (vector[i] == valor) {encontrado = 1; /*Verdadeiro*/} else {i++;}}

Page 7: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa sequencial

3º passo | tratamento do resultado

i{ (encontrado) {print{ ("Valor %d esta na posicao %d\n", vector[i], i);

} else {

print{ ("Valor %d não encontrado\n", valor);

}

Ver mais detalhes em sequencial.c

Page 8: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Exemplo - sequencial.c#include <stdio.h>

#define TAMANHO 10

int main () {

int vector[TAMANHO] = {0,3,4,7,5,2,9,6,1,8};int valor = 20;int i;int encontrado;

i = 0;encontrado = 0; /*falso*/

while (i < TAMANHO && !encontrado) {if (vector[i] == valor) {encontrado = 1; /*Verdadeiro*/

} else {i++;

}}

if (encontrado) {printf ("Valor %d encontrado na posicao %d\n", vector[i], i);

} else {printf ("Valor %d nao encontrado\n", valor);

}

return 0;}

Page 9: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Exemplo - sequencial.c (2)

Page 10: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa sequencial

Quanto tempo este algoritmo demora a executar? Em outras palavras, quantas vezes a comparação

valor == vector[i]

é executada?

Page 11: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa sequencial

caso valor não esteja presente no vector, n vezes.

caso valor esteja presente no vector,1 vez no melhor caso (valor está na primeira posição).n vezes no pior caso (valor está na última posição).n/2 vezes no caso médio.

Page 12: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa binária (dicotómica)

Vamos supor agora que o vector inicial estava ordenado por ordem crescente (se fosse por ordem decrescente o raciocínio era semelhante). Será que é possível resolver o problema de modo mais eficiente?

Page 13: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa dicotómica

Caso a lista esteja ordenada, sabemos que, para qualquer i e j, i < j, se, e somente se, A[i] ≤ A[j].

Portanto, comparando um determinado elemento com o elemento procurado, saberemos

se o elemento procurado é o elemento comparado,se ele está antes do elemento comparado ouse está depois.

Page 14: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa dicotómica

Se fizermos isso sempre com o elemento do meio da lista, a cada comparação dividiremos a lista em duas, reduzindo nosso tempo de pesquisa.Se em um determinado momento o vector, após sucessivas divisões, tiver tamanho zero, então o elemento não está no vector.

Ver mais detalhes em binaria.c

Page 15: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Exemplo - binaria.c#include <stdio.h>

#define TAMANHO 10

int main () {

int vector[TAMANHO] = {0,1,2,3,4,5,6,7,8,9};int valor = 8;int encontrado;

int direita, esquerda, meio;

encontrado = 0; /*falso*/

esquerda = 0;direita = TAMANHO - 1;

while (esquerda <= direita && !encontrado) {meio = (direita + esquerda) / 2;if (vector[meio] == valor)encontrado = 1; /*Verdadeiro*/

else if (valor < vector[meio])direita = meio - 1;

elseesquerda = meio + 1;

}

if (encontrado) {printf ("Valor %d encontrado na posicao %d\n", vector[meio], meio);

} else fprintf ("Valor %d não encontrado\n", valor);

}

return 0;}

Page 16: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Exemplo - binaria.c (2)

Page 17: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa dicotómica

Quanto tempo o algoritmo de busca binária demora a executar? Por outras palavras, quantas vezes a comparação

valor == vector[i]

é executada?

Page 18: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Pesquisa dicotómica

caso o valor não exista no vector, log2(n) vezes.

caso valor exista no vector,1 vez no melhor caso (valor é a mediana do vector).log2(n) vezes no caso médio.

Veja exemplos em bin-random.c

Page 19: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Qual dos dois algoritmos é melhor?

Para n = 1000, o algoritmo de pesquisa sequencial irá executar 1000 comparações no pior caso, 500 operações no caso médio.

Por sua vez, o algoritmo de pesquisa binária irá executar 10 comparações no pior caso, para o mesmo n. O logaritmo de base 2 aparece porque estamos sempre a dividir o intervalo ao meio: 1000, 500, 250, 125, 63, 32, 16, 8, 4, 2, 1.

Page 20: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Qual dos dois algoritmos é melhor?

O algoritmo de pesquisa dicotómica assume que o vector está ordenado. Ordenar um vector também tem um custo, superior ao custo da pesquisa sequencial.

Se for para fazer uma só pesquisa, não vale a pena ordenar o vector. Por outro lado, se pretendermos fazer muitos pesquisas, o esforço da ordenação já poderá valer a pena.

Page 21: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação

3 métodos:

Ordenação por inserçãoOrdenação por selecçãoOrdenação por bolha

Page 22: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação

Dado um conjunto de n elementos,representado num vector de 0 a n-1,

procura-se obter um outro conjunto, cujos elementos estejam ordenados segundo algum critério de comparação entre os elementos.

Page 23: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por inserção

A proposta da ordenação por inserção é:

Para cada elemento do vector faça:insira-o na sua posição correspondente;

Page 24: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por inserçãoDurante o processo de ordenação por inserção a lista (ou vector) fica dividida em dois sub-vectores, um com os elementos já ordenados e o outra com elementos ainda por ordenar.No inicio, o sub-vector ordenado é formado trivialmente apenas pelo primeiro elemento do vector.Nos métodos de ordenação por inserção, a cada etapa i, o i-esimo elemento é inserido no seu lugar apropriado entre os i ≤ 1 elementos já ordenados. Os índices dos itens a serem inseridos variam 2 a tamanho.

Page 25: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por inserçãoPassagem V[0] V[1] V[2] V[3] V[4]Vector original 9 8 7 6 5

1 {8 9} {7 6 5}2 {7 8 9} {6 5}3 {6 7 8 9} {5}4 {5 6 7 8 9}

mais detalhes em insercao.c

Page 26: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por inserção

Em cada etapa i são executadas no máximo, i comparações pois o ciclo interno éexecutado para j de i ≤ 1 até 0.

Como i varia de 0 até tamanho ≤ 1, o numero total de comparações para ordenar o vector todo é da ordem de tamanho2 .

Page 27: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Exemplo insercao.c#include <stdio.h>

#define TAMANHO 10

int main () {

int vector[TAMANHO] = {37,54,21,68,91,2,51,64,34,25};int i, j, aux;

for(i = 1; i < TAMANHO; i++) {aux = vector[i];for(j = i-1; (j >= 0) && (aux < vector[j]); j--)

vector[j + 1] = vector[j];vector[j + 1] = aux;

}

printf ("f%d", vector[0]);

for (i = 1; i < TAMANHO; i++) {printf (", %d", vector[i]);

}

printf ("}\n");

return 0;}

Page 28: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Exemplo insercao.c

Page 29: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por selecção

A ordenação por selecção consiste, em cada etapa, em seleccionar o maior (ou o menor) elemento e coloca-lo em sua posição correcta dentro do futuro vector ordenado.

Page 30: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por selecçãoDurante a aplicação do método de selecção o vector com m registos fica decomposto em dois sub-vectores, um contendo os itens já ordenados e o outro com os restantes ainda não ordenados. No início o sub-vector ordenado está vazia e o outro contem todos os outros. No final do processo o sub-vector ordenado apresentará tamanho ≤ 1 itens e o outro apenas 1.

Cada etapa (ou passagem) como já descrita acima consiste em buscar o maior elemento da vector não ordenado e coloca-lo no vector ordenado.

Page 31: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por selecção

Passagem V[0] V[1] V[2] V[3] V[4]Vector original 5 9 1 4 3

1 {5 3 1 4 } {9}2 {4 3 1} {5 9}3 {1 3} {4 5 9}4 {1} {3 4 5 9}

Page 32: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Exemplo - selecao.c#include <stdio.h>#include <limits.h>

#define TAMANHO 10

int main () {

int vector[TAMANHO] = {37,54,21,68,91,2,51,64,34,25};int valor = 20;int i, j, aux, maior;

for(i=0;i<TAMANHO-1;i++) {maior=INT_MIN;for(j=0;j<TAMANHO-i;j++)if (vector[j] > vector[maior])

maior=j;

aux=vector[TAMANHO-i-1];vector[TAMANHO-i-1]=vector[maior];vector[maior]=aux;

}

printf ("{%d", vector[0]);

for (i = 1; i < TAMANHO; i++) {printf (", %d", vector[i]);

}

printf ("}\n");

return 0;}

Page 33: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Exemplo - selecao.c

Page 34: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por selecção

A comparação é feita no ciclo mais interno. Para cada valor de i são feitas tamanho ≤ icomparações dentro do ciclo mais interno. Como i varia de 0 até tamanho ≤ 1, o número total de comparações para ordenar o vector todo é, novamente, da ordem de tamanho2.

Page 35: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por bolha (bubble)

Um método simples de ordenação por troca éa estratégia conhecida como bolha que consiste, em cada etapa “borbulhar" o maior elemento para o elemento m do vector.Inicialmente percorre-se o vector a ordenar da esquerda para a direita, comparando pares de elementos consecutivos, trocando de lugar os que estão fora da ordem. No exemplo a seguir, a cada troca, o maior elemento é deslocado uma posição para a direita.

Page 36: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por bolha (bubble)

Passagem V[0] V[1] V[2] V[3] Troca1 10 9 7 6 V[0] e V[1]

9 10 7 6 V[1] e V[2]9 7 10 6 V[2] e V[3]9 7 6 10 fim da passagem 1

Page 37: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por bolha (bubble)

Após a primeira a passagem, o maior elemento encontra-se colocado na sua posição definitiva na lista ordenada.

Podemos deixa-lo de lado e efectuar a segunda passagem no sub-vectorV[0],V[1],V[2].

Vejam a continuação do exemplo:

Page 38: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por bolha (bubble)

Passagem V[0] V[1] V[2] V[3] Troca2 9 7 6 10 V[0] e V[1]

7 9 6 10 V[1] e V[2]

7 6 9 10 fim da passegm 2

Page 39: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por bolha (bubble)

Após o segundo varrimento o maior elemento do sub-vector V[0],V[1],V[2] encontra-se colocado na sua posição definitiva. O próximo sub-vector a ser ordenada éV[0],V[1].

Vejam a continuação do exemplo:

Page 40: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por bolha (bubble)

Passagem V[0] V[1] V[2] V[3] Troca3 7 6 9 10 V[0] e V[1]

6 7 9 10 fim da passegm 3

Page 41: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Ordenação por bolha (bubble)

No algoritmo da bolha observamos que existem tamanho ≤1 varrimentos (etapas) e que em cada varrimento o número de comparações diminui de uma unidade, variando de tamanho ≤1 até 1. Portanto, para ordenar o vector todo novamente precisamos de aproximadamente tamanho2

comparações.

Page 42: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Exemplo bolha.c#include <stdio.h>

#define TAMANHO 10

int main () {

int vector[TAMANHO] = {37,54,21,68,91,2,51,64,34,25};int i, j, aux;

for(i=0;i<TAMANHO-1;i++) {for(j=0;j<TAMANHO-i-1;j++)if (vector[j] > vector[j+1]) {

aux=vector[j];vector[j]=vector[j+1];vector[j+1]=aux;}

}

printf ("{%d", vector[0]);

for (i = 1; i < TAMANHO; i++) {printf (", %d", vector[i]);

}

printf ("}\n");

return 0;}

Page 43: Introdução à Programação 2006/07 - IPSltodi.est.ips.pt/ip/ficheiros/pesquisa_ordenacao.pdf · Introdução à Programação 2006/2007 Pesquisa dicotómica Se fizermos isso sempre

Introdução à Programação 2006/2007

Exemplo bolha.c (2)