📘 Exercícios — Capítulo 8#
Ordenação#
8.1 Ordenando uma Lista#
Exercício 8.1 — Bolha com nomes#
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', 'Gilliam', '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, ou ‘cleese’?
Ver solução
Exercício — Bolha com nomes#
# Ordenação por borbulhamento (bubble sort) com lista de nomes
lista = ['Cleese', 'Palin', 'Jones', 'Idle', 'Gilliam', 'Chapman']
print('Lista original:', lista)
n = len(lista)
for j in range(n - 1):
for i in range(n - 1 - j):
if lista[i] > lista[i + 1]:
lista[i], lista[i + 1] = lista[i + 1], lista[i]
print('Lista ordenada:', lista)
Exercício 8.2 — Bolha com sentinela#
Uma melhoria pode ser feita no algoritmo da bolha com sentinela: note que a cada passagem pela lista, a última troca de elementos deixa um elemento na sua posição correta. Após esta posição, os elementos têm de estar ordenados e nos próximos passos não é necessário ir além desta posição. Escreva um programa que guarde esta posição e que a utilize como sentinela. O algoritmo a ser implementado em Python é o seguinte:
Seja uma lista com n elementos
limite = tamanho da lista - 1
ultimo = limite
Enquanto limite != 0:
limite = 0
Para i variando entre 0 e ultimo - 1:
Se lista[i] > lista[i+1]
troque elementos de posição.
limite = i
ultimo = limiteEste algoritmo usa a variável limite para indicar qual elemento não
sabemos ainda estar na sua posição final. A variável ultimo indica o índice
no qual foi realizada a última troca entre posições de elementos. Se nenhuma
troca for realizada, limite permanece em zero e o algoritmo termina.
Ver solução
Exercício — Bolha com sentinela#
# Ordenação por borbulhamento com sentinela e posição da última troca
lista = [64, 34, 25, 12, 22, 11, 90]
print('Lista original:', lista)
n = len(lista)
limite = n - 1
ultimo = limite
while limite != 0:
limite = 0
for i in range(ultimo):
if lista[i] > lista[i + 1]:
lista[i], lista[i + 1] = lista[i + 1], lista[i]
limite = i
ultimo = limite
print('Lista ordenada:', lista)
8.2 Ordenação por Inserção#
Exercício 8.3 — Ordenação por inserção#
A partir da definição do algoritmo de ordenação, siga os mesmos passos de desenvolvimento do algoritmo da bolha para chegar à sua própria versão do algoritmo de ordenação por inserção.
Ver solução
Exercício — Ordenação por inserção#
# Ordenação por inserção (insertion sort)
def ordenacao_insercao(lista):
for j in range(1, len(lista)):
chave = lista[j]
i = j - 1
while i >= 0 and lista[i] > chave:
lista[i + 1] = lista[i]
i -= 1
lista[i + 1] = chave
lista = [64, 34, 25, 12, 22, 11, 90]
print('Lista original:', lista)
ordenacao_insercao(lista)
print('Lista ordenada:', lista)
Exercício 8.4 — Inserção recursiva#
Um algoritmo recursivo para o ordenamento por inserção seria:
- Se lista tem tamanho igual ou menor que 1, retorne
- Recursivamente ordene os primeiros n−1 elementos
- Insira o último elemento na parte já ordenada
Você poderia escrever a função desse algoritmo? Perceba que a inserção ainda deve ser feita com um laço. Este algoritmo não ganha em ser implementado recursivamente. O desempenho das duas versões é equivalente.
Ver solução
Exercício — Inserção recursiva#
# Ordenação por inserção recursiva
def insercao_recursiva(lista, n):
if n <= 1:
return
insercao_recursiva(lista, n - 1)
chave = lista[n - 1]
i = n - 2
while i >= 0 and lista[i] > chave:
lista[i + 1] = lista[i]
i -= 1
lista[i + 1] = chave
lista = [64, 34, 25, 12, 22, 11, 90]
print('Lista original:', lista)
insercao_recursiva(lista, len(lista))
print('Lista ordenada:', lista)
Exercício 8.5 — Intercalação de listas#
Escreva uma função que intercale duas listas. O programa deve receber duas listas já ordenadas e criar uma terceira lista que é o resultado da intercalação dos elementos dos dois conjuntos de modo que a nova lista também esteja ordenada.
Ver solução
Exercício — Intercalação de listas#
# Intercalação de duas listas ordenadas
def intercala(lista1, lista2):
resultado = []
i = 0
j = 0
while i < len(lista1) and j < len(lista2):
if lista1[i] <= lista2[j]:
resultado.append(lista1[i])
i += 1
else:
resultado.append(lista2[j])
j += 1
resultado.extend(lista1[i:])
resultado.extend(lista2[j:])
return resultado
lista1 = [1, 3, 5, 7, 9]
lista2 = [2, 4, 6, 8, 10]
print('Lista 1:', lista1)
print('Lista 2:', lista2)
print('Intercalada:', intercala(lista1, lista2))
Exercício 8.6 — Mergesort#
Um algoritmo bem eficiente de ordenação é o mergesort. Seu princípio é a divisão do conjunto a ser ordenado em duas partes, ordenar cada parte, e depois fazer uma fusão (merge) entre os dois conjuntos ordenados. Cada vez que for ordenar uma metade, o algoritmo é chamado recursivamente, dividindo à metade cada parte que deveria ordenar. Quando a parte a ser ordenada contiver apenas 1 elemento, o algoritmo retorna.
Escreva uma função mergesort que receba uma lista e ordene-a segundo esse algoritmo. Para a função de intercalação, use a que você criou no exercício anterior. O algoritmo é o seguinte:
merge_sort(a)
se lista tem tamanho menor ou igual a 1 retorne a
m = tamanho de a dividido por 2
a0 = merge_sort(a[:m])
a1 = merge_sort(a[m:])
merge(a0, a1, a)No algoritmo, a0 é a primeira metade da lista; a1 é a segunda metade e a é a
lista que guarda a intercalação das duas.
Ver solução
Exercício — Mergesort#
# Ordenação mergesort
def intercala(lista1, lista2):
resultado = []
i = 0
j = 0
while i < len(lista1) and j < len(lista2):
if lista1[i] <= lista2[j]:
resultado.append(lista1[i])
i += 1
else:
resultado.append(lista2[j])
j += 1
resultado.extend(lista1[i:])
resultado.extend(lista2[j:])
return resultado
def merge_sort(a):
if len(a) <= 1:
return a
m = len(a) // 2
a0 = merge_sort(a[:m])
a1 = merge_sort(a[m:])
return intercala(a0, a1)
lista = [64, 34, 25, 12, 22, 11, 90]
print('Lista original:', lista)
lista = merge_sort(lista)
print('Lista ordenada:', lista)
Quer ir além?#
Se você quiser se desafiar com novos problemas, sem solução disponível:
👉 Exercícios extras do Capítulo 8
e também: