Algoritmos Computacionais

Artigos sobre lógica de programação por Tiago Madeira

algoritmo: do Lat. algorithmos < Ár. alkharizmi: [Inform.] conjunto de etapas bem definidas necessárias para chegar à resolução de um problema.

Archive for the 'Ordenação' Category

Ordenação por Seleção

Friday, January 13th, 2006

Hoje vou apresentar mais um algoritmo de ordenação de vetores. É a Ordenação por Seleção (ou Selection Sort). Sem mais papo e antes mesmo da explicação, vamos ao seu pseudocódigo:

1. para i LaTeX: leftarrow{} 1 até tamanho-1, faça
2.	minimo LaTeX: leftarrow{} i
3.	para j LaTeX: leftarrow{} i+1 até tamanho, faça
4.		se vetor[j] < vetor[minimo], então
5.			minimo LaTeX: leftarrow{} j
6.		fim-se
7.	fim-para
8.	temp LaTeX: leftarrow{} vetor[i]
9.	vetor[i] LaTeX: leftarrow{} vetor[minimo]
10.	vetor[minimo] LaTeX: leftarrow{} temp
11. fim-para

tamanho = comprimento do vetor

Funcionamento

A idéia é sempre procurar o menor elemento do vetor e inseri-lo no início do vetor. Procuramos o menor valor do vetor e colocamos ele em vetor[1]. Procuramos o menor valor do vetor excluindo o já colocado e colocamos ele em vetor[2]. E assim vamos indo até termos todo o vetor ordenado.

Partindo sempre a partir do último elemento reordenado (a partir do i), o programa procura o menor elemento no vetor e o substitue pelo elemento i atual.

Exemplo de Funcionamento

O programa recebe o seguinte vetor.

v[1] v[2] v[3] v[4] v[5] v[6]
5 3 7 8 2 5

Aí ele começa com LaTeX: i=1. Vou sempre marcar LaTeX: i com a cor preta e LaTeX: min com a cor cinza.

v[1] v[2] v[3] v[4] v[5] v[6]
5 3 7 8 2 5

Ele marca o próprio índice i como a variável minimo, que é sempre o menor elemento do vetor. Então, ele faz um para de LaTeX: j=2 até o comprimento do vetor, com o objetivo de descobrir qual o menor elemento.

LaTeX: j=2 ... LaTeX: v[j] = 3 < v[minimo] = v[1] = 5, portanto LaTeX: minimo = j = 2.

v[1] v[2] v[3] v[4] v[5] v[6]
5 3 7 8 2 5

LaTeX: j=3 ... LaTeX: v[j] = 7 > v[minimo] = v[2] = 3, portanto não mexemos em nada.

LaTeX: j=4 ... LaTeX: v[j] = 8 > v[minimo] = v[2] = 3, portanto não mexemos em nada.

LaTeX: j=5 ... LaTeX: v[j] = 2 < v[minimo] = v[2] = 3, portanto LaTeX: minimo = j = 5.

v[1] v[2] v[3] v[4] v[5] v[6]
5 3 7 8 2 5

LaTeX: j=6 ... LaTeX: v[j] = 5 > v[minimo] = v[5] = 2, portanto não mexemos em nada.

Agora substituímos o v[minimo] pelo v[i], formando com isto o novo vetor:

v[1] v[2] v[3] v[4] v[5] v[6]
2 3 7 8 5 5

E assim vamos fazendo com os outros elementos até que todo o vetor esteja ordenado.

Custo

Este algoritmo não tem um melhor/pior caso, porque todos os elementos são varridos, sempre. Medir seu custo é simples. Custo de linha por linha...

n = tamanho do vetor

  1. LaTeX: n
  2. LaTeX: n-1
  3. LaTeX: \sum_{j=1}^{n} + n
  4. LaTeX: \sum_{j=1}^{n}
  5. LaTeX: \sum_{j=1}^{n} ???
  6. LaTeX: 0
  7. LaTeX: 0
  8. LaTeX: n-1
  9. LaTeX: n-1
  10. LaTeX: n-1
  11. LaTeX: 0

Você pode estar se perguntando porque eu coloquei este custo para a linha 5. Afinal, a linha 5 diria que este programa tem um melhor/pior caso, porque ela não seria executada se o se retornar falso. Mas o caso é que ela é desprezível. Uma soma como estas para o custo geral do nosso algoritmo não vai influenciar em nada. Quer ver? Vamos somar os custos com esta linha valendo LaTeX: 0 (como se nenhum se entrasse) e depois com ela valendo LaTeX: \sum_{j=1}^{n}.

Primeiro cálculo

LaTeX: T(n) LaTeX: = LaTeX: (n) LaTeX: + LaTeX: (n-1) LaTeX: + LaTeX: (\sum_{j=1}^{n} + n) LaTeX: + LaTeX: (\sum_{j=1}^{n}) LaTeX: + LaTeX: (0) LaTeX: + LaTeX: (0) LaTeX: + LaTeX: (0) LaTeX: + LaTeX: (n-1) LaTeX: + LaTeX: (n-1) LaTeX: + LaTeX: (n-1) LaTeX: + LaTeX: (0)

LaTeX: T(n) = n^{2} + 6n -3

LaTeX: \Theta{}(n^{2}) = f(n)

Segundo cálculo

LaTeX: T(n) LaTeX: = LaTeX: (n) LaTeX: + LaTeX: (n-1) LaTeX: + LaTeX: (\sum_{j=1}^{n} + n) LaTeX: + LaTeX: (\sum_{j=1}^{n}) LaTeX: + LaTeX: (\sum_{j=1}^{n}) LaTeX: + LaTeX: (0) LaTeX: + LaTeX: (0) LaTeX: + LaTeX: (n-1) LaTeX: + LaTeX: (n-1) LaTeX: + LaTeX: (n-1) LaTeX: + LaTeX: (0)

LaTeX: T(n) = 1,5 n^{2} + 6,5 n - 3

LaTeX: \Theta{}(n^{2}) = f(n)

Conclusão

Como vocês puderam ver, não faz diferença alguma o LaTeX: \frac{n^{2} + n}{2} que aquela somatória nos proporciona. Já que todo o cálculo de algoritmos é baseado apenas no maior expoente de n e desprezamos todas as constantes (inclusive as que multiplicam o n de maior expoente, muitos passos são desprezíveis.


Espero que tenham gostado! Qualquer dúvida, sugestão ou notificação de erro; poste um comentário ou me envie um e-mail.

Compare Preços de: notebooks, acer aspire, hp pavilion, computadores, pentium 4, nintendo wii, ps3, celulares, câmeras digitais

Ordenação por Inserção

Wednesday, January 11th, 2006

Também conhecida como Insertion Sort, a Ordenação por Inserção consiste em inserir um elemento LaTeX: n num vetor já ordenado de LaTeX: n-1 elementos. Neste artigo, apresento-lhes este simples algoritmo para ordenação de vetores.

O pseudocódigo da ordenação por inserção é o seguinte:

1. para j LaTeX: leftarrow{} 2 até comprimento do vetor, faça
2.	elemento LaTeX: leftarrow{} vetor[j]
3.	i LaTeX: leftarrow{} j - 1
4.	enquanto i > 0 e vetor[i] > elemento, faça
5.		vetor[i + 1] LaTeX: leftarrow{} vetor[i]
6.		i LaTeX: leftarrow{} i - 1
7.	fim-enquanto
8.	vetor[i + 1] LaTeX: leftarrow{} elemento
9. fim-para

Para explicar eu vou fazer uma coisa que sempre faço para corrigir meus algoritmos, fingir que sou o programa, executando cada passo manualmente (claro que geralmente faço mais rápido, porque não preciso escrever tudo que faço). Vamos iniciar com o seguinte vetor v.

v[1] v[2] v[3] v[4] v[5] v[6]
5 3 7 8 2 5

Aí o código me manda começar com LaTeX: j=2 e iterar até o comprimento do vetor (6). A primeira ordem que ele me dá é para armazenar o elemento LaTeX: a[j] (LaTeX: a[2]) na variável elemento. Para facilitar toda a explicação eu vou sempre pintar de cinza o LaTeX: v[j] onde eu estou (no caso, o segundo elemento do vetor, 3) e de preto o vetor ainda não ordenado (elementos LaTeX: \geq{}j).

v[1] v[2] v[3] v[4] v[5] v[6]
5 3 7 8 2 5

Então ele me diz que LaTeX: i \leftarrow{} j-1. Portanto, LaTeX: i=1. E agora ele me faz um enquanto (que poderia ser substituído por para) onde meu i deverá ir diminuindo. Vamos entrar no loop...

Bom, meu LaTeX: i =1 é maior que 0. LaTeX: v[1]=5 é maior que o LaTeX: elemento=3? Sim, então vamos entrar no corpo do enquanto... Aqui ele me manda fazer um LaTeX: vetor[i+1] = vetor[i], que nesse caso é fazer um LaTeX: v[2]=v[1]=5.

v[1] v[2] v[3] v[4] v[5] v[6]
5 5 7 8 2 5

E agora subtrae de i um valor. Portanto, LaTeX: i=0. Ele retorna ao enquanto, mas agora não satisfazemos a condição LaTeX: i>0, por isso saímos do enquanto. Então ele pede para LaTeX: vetor[i+1]=elemento (LaTeX: v[1]=elemento). Portanto, o vetor fica assim:

v[1] v[2] v[3] v[4] v[5] v[6]
3 5 7 8 2 5

E incrementamos o j, agora LaTeX: j=3.

v[1] v[2] v[3] v[4] v[5] v[6]
3 5 7 8 2 5

LaTeX: elemento = 7

LaTeX: i = 3-1 = 2

LaTeX: i > 0 ... E LaTeX: 5 > 7? Não! Portanto, não entramos no enquanto.

LaTeX: v[3] = elemento (nenhuma mudança)

E lá vamos para LaTeX: j=4 e continuando até que vamos ter o vetor ordenado:

v[1] v[2] v[3] v[4] v[5] v[6]
2 3 5 5 7 8

Qual a lógica?

Como eu já disse na introdução, mas lá sem grandes explicações, a Ordenação por Inserção divide o vetor em dois. O primeiro (de elementos LaTeX: <j) contém todos seus valores ordenados e o segundo (de elementos LaTeX: \geq{}j) contém os valores que devem ser inseridos no primeiro vetor já ordenado (por isso ele se chama Algoritmo de Inserção).

A chave do algoritmo é o enquanto que acontece para ir deslocando todos os elementos para seu índice LaTeX: +1 enquanto o elemento for menor que eles (para depois o elemento ser colocado onde parou).

A variável elemento só serve para não perdermos o valor de LaTeX: v[j] (porque depois fazemos LaTeX: v[i+1]=v[i] quando LaTeX: i=j-1)

Acredito que não tenham restado dúvidas. Dê mais uma olhada no algoritmo e tente implementar. Se tiver dificulade, coloque mensagens de debug estratégicas para entender o algoritmo. (ex.: no início do para coloque para imprimir o valor de j e no início de cada enquanto coloque para imprimir os valores elemento, i e v[i])

Custo

Você deve ter percebido que este algoritmo não tem um custo fixo. Se todo o vetor estiver ordenado, ele nunca precisará iterar o LaTeX: i e portanto será executado bem mais rápido do que se o vetor estiver inteiro em ordem decrescente (quando ele sempre precisará iterar LaTeX: i até o fim - 0). Então, neste artigo, gostaria-lhes de apresentar a análise de algoritmos baseada em casos. Para este programa, dizemos que:

  • Melhor caso é quando todos os elementos já estão ordenados. Custo: LaTeX: \Theta{}(n)
  • Pior caso é quando os elementos estão em ordem decrescente. Custo: LaTeX: \Theta{}(n^{2})

Em alguns programas o caso médio é importante também, mas não é o caso da ordenação por inserção. Vemos que há uma diferença bem grande entre o custo dos dois casos. Por isso, precisamos conhecer onde que nosso algoritmo será implementado e quais as chances de ele ser o melhor ou pior caso. Em geral, o pior caso é o mais comum... Por isso, diremos que o custo deste algoritmo é LaTeX: \Theta{}(n^{2}).


Por hoje é isso aí... Espero que vocês tenham gostado. Qualquer dúvida, não hesitem em perguntar! Ah... E comentem e sugiram para os próximos artigos! :)

Compare Preços de: notebooks, acer aspire, hp pavilion, computadores, pentium 4, nintendo wii, ps3, celulares, câmeras digitais

53 assinantes

Mais artigos

Comentários recentes

  • Jordana: Eu estou fazendo faculdade de ciencia da computação, na máteria de algoritmo eu estou...
  • wagnermoral: ola pessoal, to iniciadno no curso Tecnologia de Informação, e to com um...
  • Estefânia Paula: Adorei a introdução q vc fez sobre algoritmo… Gostaria de saber se tem...
  • Arnaldo: Estou no primeiro periodo de Sistemas de Informação. Estou com dúvidas em como...
  • milena de brito sampaio alencar barros: oi tiago! nossa cara valeu mesmo pela explicação do que...
  • Cleidson Lima da Silva: Bom gostei muito do artigo, explicou de uma maneira mais fácil de ser...
  • svjwbrxyz bnqtiruv: hsxcwrv mnxlhw pfgwc nedqmyo cskfqt vtzihdf ybdtaumqp
  • plvr ybncof: pksgtlvwd rauskizvj ebky shjmgoqy nyxlqvbwm sjuexr wote
  • marconi: caros colegas estou com uma grande dificuldade,preciso de um exemplo de algoritmo q...
  • Tatiane Hendler: Não é possível não, todos os elementos que aparecerem no teu algoritmo deve,...

Categorias

Escrevo também...

  • Tiago Madeira
    Site pessoal e blog do autor destes artigos
  • Mal Vicioso
    Blog sobre filosofia e sobre a hipocrisia da sociedade

Links

Sobre o design

Este design foi copiado do CSS Zen Garden e modificado com autorização de seu autor, Gunta Klavina.

Licença

Todo o conteúdo deste site (incluindo textos, imagens, arquivos de áudio e quaisquer outros trabalhos), exceto quando especificado o contrário, está licenciado por Tiago Madeira sob uma Licença Creative Commons.

HTML 4.01 gerado por WordPress em 0.613 segundos.