5.10 Er gaat iets mis — top-3 fouten
Leerdoel: je herkent de klassieke valkuilen bij selection sort.
Zoeken vanaf index 0 in plaats van vanaf i
Geen Python-foutmelding — wél een stille fout: de al-gesorteerde elementen vooraan worden door nieuwe swaps overschreven.
Oorzaak: elke ronde zoek je nog steeds in de hele lijst — ook in
het al gesorteerde stuk vooraan. En je swapt met lijst[i], wat een
al-gesorteerde plek kan zijn. Het sorted-stuk wordt vernield.
Oplossing: zoek vanaf i en begin de zoektocht met min_index = i.
Zo laat je het al-gesorteerde deel met rust.
# FOUT
def selection_sort_fout(lijst):
n = len(lijst)
for i in range(n):
min_index = 0
for j in range(0, n):
if lijst[j] < lijst[min_index]:
min_index = j
lijst[i], lijst[min_index] = lijst[min_index], lijst[i]
return lijst
# GOED
for i in range(n):
min_index = i
for j in range(i, n):
...
Verkeerde swap — informatie verliezen
Oorzaak: je overschrijft lijst[a] met lijst[b] voordat je de
oude waarde van lijst[a] ergens hebt bewaard. Daarna is de oude waarde
weg.
Oplossing: gebruik een tijdelijke variabele, of de Pythonische tuple-swap.
# FOUT
lijst = [5, 2, 8, 1, 4]
a, b = 0, 3
lijst[a] = lijst[b] # lijst[0] wordt 1; de 5 is weg
lijst[b] = lijst[a] # lijst[3] wordt 1 (alweer)
# GOED (klassiek)
tijdelijk = lijst[a]
lijst[a] = lijst[b]
lijst[b] = tijdelijk
# GOED (Pythonisch)
lijst[a], lijst[b] = lijst[b], lijst[a]
Meer uitleg: Bouwsteen 2 — swappen.
range(0, n) in plaats van range(i, n) in de binnenste lus
Geen Python-foutmelding — werkt toevallig soms, maar de logica klopt niet.
Oorzaak: in ronde i = 2 kijken we óók nog naar lijst[0] en
lijst[1]. Maar die zijn al gesorteerd — daar zou het kleinste element
van het hele ongesorteerde stuk niet meer kunnen liggen. Risico: lijst[0]
(de allerkleinste) wordt opnieuw als min_index gekozen → swap met
lijst[i] → sorted-stuk vernield.
Oplossing: for j in range(i, n). Alleen het ongesorteerde stuk
doorzoeken.
# FOUT
for i in range(n):
min_index = i
for j in range(0, n): # begint bij 0
if lijst[j] < lijst[min_index]:
min_index = j
lijst[i], lijst[min_index] = lijst[min_index], lijst[i]
# GOED
for i in range(n):
min_index = i
for j in range(i, n): # begint bij i
if lijst[j] < lijst[min_index]:
min_index = j
lijst[i], lijst[min_index] = lijst[min_index], lijst[i]
Door naar stap 11: cheatsheet.