Introdução à programação e aos algoritmos

João Araujo Ribeiro · Capítulo 93 de 103

Páginas do PDF

Introdução à programação e aos algoritmos

8.1.1 Sentinela

Como você pode saber se uma lista está ordenada? No algoritmo do ordenamento por borbulhamento é feita a comparação de elementos consecutivos de uma lista. Se em uma passagem não houver nenhuma troca, é porque a lista está ordenada e nada mais há para fazer, e pode-se dar o trabalho por concluído.

Uma forma simples de detectar se a lista está ordenada é usar

uma variável que controla se houve ou não uma mudança em determinada condição. Desse modo, em nosso exemplo de ordenação de lista, começamos acreditando que a lista está fora de ordem. Sabemos que a lista estará ordenada e poderemos parar, quando for feita uma passagem completa por todos os seus elementos sem que haja nenhuma troca, ou seja, em nenhum momento, durante essa passagem, o comando “if lista[j] > lista[j+1]:” teve como resultado verdade.

No nosso exemplo, vamos usar uma sentinela chamada

fora_de_ordem. Inicialmente seu valor é verdadeiro ( True), indicando que a lista está fora de ordem. Enquanto seu valor for verdadeiro, vamos continuar a varrer a lista, procurando elementos consecutivos fora de ordem. Para tanto, usaremos um artifício: logo antes de entrar no laço que faz essa varredura; faremos a sentinela ser falsa; mas, se alguma troca de elementos for realizada, o laço volta a ser verdade, indicando que a lista ainda não está ordenada. Quando o programa terminar o laço, se nenhuma troca foi feita, a sentinela continua com valor falso e o laço principal não executa outra vez, terminando o algoritmo; porém, se tiver havido alguma troca, o laço principal executa mais uma varredura.

A versão do algoritmo com sentinela seria:

Seja uma lista com n elementos

fora_de_ordem = verdade

Enquanto fora_de_ordem:

fora_de_ordem = falso

Para i variando entre 0 e n-2:

Se lista[i] > lista{i+1}

troque elementos de posição.

fora_de_ordem = verdade

O comando

Enquanto fora_de_ordem:

poderia ser escrito como

Enquanto fora_de_ordem == verdade:

mas isso seria redundante: o comando “ Enquanto” executa um laço enquanto uma condição for verdadeira, portanto, testar esta condição explicitamente é desnecessário. Além do mais, “ Enquanto fora_de_ordem: ” fica bem mais elegante e próximo ao português do que a versão explícita. O programa 8.3 traduz este algoritmo para Python.

def bubblesort(lista):

“““Ordena uma lista pelo método da bolha”””

n = len(lista)

fora_de_ordem = True

while fora_de_ordem:

fora_de_ordem = False

for j in range(n - 1):

if lista[j] > lista[j + 1]:

lista[j],lista[j + 1] = lista[j + 1],lista[

j]

fora_de_ordem = True

print(lista)

lista_desordenada = [

503, 87, 512, 61, 908, 170, 897, 275, 653, 426,

154,

509, 612, 677, 765, 703

]

bubblesort(lista_desordenada)

 

■ Programa 8.3: programa de ordenação pelo método da bolha

com sentinela.

Em relação à versão sem a sentinela, o novo programa

economizou uma execução do laço. Pode parecer pouco, mas imagine que nossa lista já estivesse ordenada desde o início. O primeiro programa executaria o mesmo número de vezes, dependente apenas do tamanho da lista, enquanto a nova versão executaria o laço apenas uma vez e, ao terminar a primeira execução do laço, detectaria que a lista já estava ordenada e terminaria o programa.

Isso nos leva a uma conclusão interessante: apesar de ser

considerado um dos piores algoritmos de ordenação, o algoritmo da bolha pode ser o mais eficiente no caso particular em que a lista a ser ordenada já está ordenada! Não é muito útil, mas é um fato. Esse algoritmo detecta mais rapidamente que outros algoritmos essa condição, porém será extremamente ineficiente se o menor elemento estiver na última posição da lista. Neste caso, a cada passagem, este elemento “desce” apenas uma posição, e o programa vai precisar executar n-1 vezes para terminar de ordenar todos os elementos, e no caso de se usar sentinela, ainda executará uma última vez para confirmar se a lista está ordenada.

 

EXERCÍCIO 8.1

 

Python pode comparar strings diretamente com os operadores de comparação

usuais. Use o algoritmo da ordenação por borbulhamento para ordenar uma lista

de nomes. Para tanto, basta substituir a lista de números original por uma com

nomes, por exemplo:

lista = [‘Cleese’, ‘Palin’, ‘Jones’, ‘Idle’, ‘Gillia

m’, ‘Chapman’]

(como curiosidade, estes são os nomes dos atores do grupo Monty Python,

inspiração para o nome da linguagem Python)

Coloque mais palavras, e veja a diferença entre letras maiúsculas e

minúsculas. Qual palavra vem antes, ‘Cleese’, com c maiúsculo, e ‘cleese’.