Drop links or images here to add them to the editor.

Het eerste algoritme dat we van naderbij bekijken, is een sorteeralgoritme: het zet de elementen van een array in volgorde, oplopend of aflopend. We gebruiken bubblesort, een eenvoudig algoritme dat werkt volgens de techniek brute force.

Het idee: vergelijken en wisselen

Bubblesort sorteert door herhaaldelijk twee elementen te vergelijken en ze om te wisselen wanneer ze in de verkeerde volgorde staan. Door dat genoeg keer te doen, schuift elk element vanzelf naar zijn juiste plaats.

Bubblesort wordt een bruteforcetechniek genoemd omdat het simpelweg alle mogelijke vergelijkingen uitvoert, zonder slimme trucs of optimalisaties. Dat is meteen de definitie van brute force: een probleem oplossen door alle mogelijkheden af te gaan.

We sorteren als voorbeeld een array van vijf namen alfabetisch:

string[] lijst = new string[5];
lijst[0] = "Jan";
lijst[1] = "Piet";
lijst[2] = "Ahmed";
lijst[3] = "An";
lijst[4] = "Max";

Het plan is om eerst het alfabetisch kleinste woord op index 0 te krijgen, dan het op één na kleinste op index 1, enzovoort:

Twee waarden van plaats wisselen

Voor we het algoritme uitschrijven, één bouwsteen: hoe wissel je de inhoud van twee variabelen? Stel woord1 = "tafel" en woord2 = "stoel", en je wil ze omdraaien. Dit lukt niet rechtstreeks:

woord1 = woord2;   // woord1 is nu "stoel" ...
woord2 = woord1;   // ... maar "tafel" is weg, dus woord2 wordt óók "stoel"!

De eerste opdracht overschrijft woord1, dus de oude waarde "tafel" is voorgoed verloren. De oplossing is een hulpvariabele die de waarde even bewaart:

hulp = woord2;     // bewaar "stoel"
woord2 = woord1;   // woord2 wordt "tafel"
woord1 = hulp;     // woord1 wordt "stoel"
woord1 woord2 hulp "tafel" "stoel" 1. hulp = woord2; "stoel" 2. woord2 = woord1; 3. woord1 = hulp;

Die hulpvariabele heb je nodig telkens je in bubblesort twee elementen omwisselt.

Woorden vergelijken met CompareTo

Voor getallen vergelijk je met < en >. Voor strings gebruik je de ingebouwde functie CompareTo, die twee woorden alfabetisch vergelijkt:

woord1.CompareTo(woord2)betekenis
0de woorden zijn gelijk
negatief (< 0)woord1 komt alfabetisch vóór woord2
positief (> 0)woord1 komt alfabetisch woord2

Zo staat lijst[i].CompareTo(lijst[j]) > 0 voor “het woord op index i komt alfabetisch ná het woord op index j”, precies de situatie waarin je beide elementen moet wisselen om oplopend (alfabetisch) te sorteren.

Het algoritme stap voor stap

Laten we de hele sortering volgen op [Jan, Piet, Ahmed, An, Max]. De buitenste lus kiest een index i; de binnenste lus vergelijkt dat element met elk later element en wisselt indien nodig. Vet staat telkens het element dat na die ronde op zijn definitieve plaats staat.

index 0index 1index 2index 3index 4vergelijkingactie
JanPietAhmedAnMax0 met 1geen wissel
JanPietAhmedAnMax0 met 2wissel (Jan > Ahmed)
AhmedPietJanAnMax0 met 3geen wissel
AhmedPietJanAnMax0 met 4geen wissel
AhmedPietJanAnMaxeinde i = 0Ahmed staat vast op index 0
AhmedPietJanAnMax1 met 2wissel (Piet > Jan)
AhmedJanPietAnMax1 met 3wissel (Jan > An)
AhmedAnPietJanMax1 met 4geen wissel
AhmedAnPietJanMaxeinde i = 1An staat vast op index 1
AhmedAnPietJanMax2 met 3wissel (Piet > Jan)
AhmedAnJanPietMax2 met 4geen wissel
AhmedAnJanPietMaxeinde i = 2Jan staat vast op index 2
AhmedAnJanPietMax3 met 4wissel (Piet > Max)
AhmedAnJanMaxPieteinde i = 3klaar: alles gesorteerd

Het eindresultaat is Ahmed An Jan Max Piet, netjes alfabetisch.

In code

De twee geneste lussen, met de hulpvariabele voor het wisselen:

int aantal = lijst.Length;   // hier: 5
string hulp;

for (int i = 0; i <= aantal - 2; i++)
{
    for (int j = i + 1; j <= aantal - 1; j++)
    {
        if (lijst[i].CompareTo(lijst[j]) > 0)   // lijst[i] komt na lijst[j]?
        {
            hulp = lijst[i];
            lijst[i] = lijst[j];
            lijst[j] = hulp;
        }
    }
}

Let op de grenzen: de buitenste i loopt van 0 tot en met aantal - 2 (het laatste element hoef je niet meer met zichzelf te vergelijken), en de binnenste j start telkens op i + 1 (alleen de elementen na i).

Bubblesort bestaat dus uit twee geneste lussen, een if met een vergelijking, en een wissel via een hulpvariabele. Voor getallen vervang je de CompareTo-vergelijking gewoon door < of >; om aflopend te sorteren draai je de vergelijking om. Dat oefen je in de volgende twee oefeningen.