Ga naar hoofdinhoud

Geavanceerde structuren

Array-manipulatie​

Een lege slot correct vinden​

Onderstaand voorbeeld laat zien hoe je met standaard codepraktijken een lege slot in een array vindt.

new
gMyArray[10];

stock FindEmptySlot()
{
new
i = 0;
while (i < sizeof (gMyArray) && gMyArray[i])
{
i++;
}
if (i == sizeof (gMyArray)) return -1;
return i;
}

Dit basisvoorbeeld gaat ervan uit dat een array-slot leeg is als de waarde 0 is. De lus loopt door alle waarden in de array (kan ook met een constant) zolang de waarden niet 0 zijn. Bij de eerste 0 faalt de while-conditie en stopt de lus zonder break. De functie retourneert -1 als er geen vrije slot is gevonden; check dat aan de aanroepende kant. Vaak gebruik je het gevonden id direct:

MyFunction()
{
new
i = 0;
while (i < sizeof (gMyArray) && gMyArray[i])
{
i++;
}
if (i == sizeof (gMyArray))
{
printf("No free slot found");
return 0;
}
printf("Slot %d is empty", i);
// Gebruik de gevonden slot
return 1;
}

Vervang uiteraard gMyArray[i] door jouw eigen indicatie dat een slot in gebruik is.

Lijst​

Introductie​

Lijsten zijn een nuttige structuur: feitelijk een array waarbij elk element naar het volgende relevante element wijst.

Voorbeeld gesorteerde lijst op indices, met start- en next-indexen:

start = 1
3, 1, 64, 2, 4, 786, 2, 9
4, 3, 5, 6, 7, -1, 0, 2

Het laatste index bij 786 is -1: einde van de lijst. Toevoegen en verwijderen kan door alleen de ‘pointers’ (next-indexen) te wijzigen in plaats van alle waarden te verplaatsen. Zie varianten en voorbeelden in de codeblokken verderop.

Typen​

  • Enkelvoudige lijst: iedere waarde wijst naar de volgende
  • Dubbele lijst: iedere waarde wijst naar zowel vorige als volgende
  • Loopende lijst: laatste wijst terug naar eerste (pas op voor eindeloze lussen)

Voorbeeld dubbele looplijst (met start, end, next, last), zie code in de Engelse versie; de structuur blijft identiek, alleen uitleg is vertaald.

Gemengde lijsten​

Gemengde lijsten combineren meerdere lijsten in één array, bv. een gesorteerde lijst en een vrije-slots-lijst om nieuwe elementen snel te plaatsen.

Code​

Kies eerst het lijsttype dat bij je toepassing past. Onderstaande voorbeelden tonen een numeriek oplopend gesorteerde gemengde lijst met een tweede lijst voor vrije slots.

#define NUMBER_OF_VALUES (10)

enum E_DATA_LIST
{
E_DATA_LIST_VALUE,
E_DATA_LIST_NEXT
}

new
gListData[NUMBER_OF_VALUES][E_DATA_LIST],
gUnusedStart = 0,
gListStart = -1; // Start zonder lijst

List_Setup()
{
new i, size = NUMBER_OF_VALUES;
size--;
for (i = 0; i < size; i++)
{
gListData[i][E_DATA_LIST_NEXT] = i + 1; // Aanvankelijk zijn alle slots vrij
}
gListData[size][E_DATA_LIST_NEXT] = -1; // Einde vrijelijst
}

List_Add(value)
{
if (gUnusedStart == -1) return -1; // Geen vrije slots
new pointer = gListStart,
last = -1,
slot = gUnusedStart;
gListData[slot][E_DATA_LIST_VALUE] = value;
gUnusedStart = gListData[slot][E_DATA_LIST_NEXT];
while (pointer != -1 && gListData[pointer][E_DATA_LIST_VALUE] < value)
{
last = pointer;
pointer = gListData[pointer][E_DATA_LIST_NEXT];
}
if (last == -1)
{
gListData[slot][E_DATA_LIST_NEXT] = gListStart;
gListStart = slot;
}
else
{
gListData[slot][E_DATA_LIST_NEXT] = pointer;
gListData[last][E_DATA_LIST_NEXT] = slot;
}
return slot;
}

List_Remove(slot)
{
if (slot < 0 || slot >= NUMBER_OF_VALUES) return 0;
new pointer = gListStart, last = -1;
while (pointer != -1 && pointer != slot)
{
last = pointer;
pointer = gListData[pointer][E_DATA_LIST_NEXT];
}
if (pointer == -1) return 0; // Niet gevonden
if (last == -1)
{
gListStart = gListData[slot][E_DATA_LIST_NEXT];
}
else
{
gListData[last][E_DATA_LIST_NEXT] = gListData[slot][E_DATA_LIST_NEXT];
}
// Voeg slot terug aan de vrije lijst
gListData[slot][E_DATA_LIST_NEXT] = gUnusedStart;
gUnusedStart = slot;
return 1;
}

Binaire bomen​

Introductie​

Binaire bomen zijn een snelle zoekmethode door telkens links/rechts te kiezen t.o.v. een middenwaarde (zoals 20-vragen). Ze ordenen niet per se data fysiek, maar bieden efficiënte zoekstructuren. De voorbeelden en afbeeldingen (binary tree) uit de originele tekst zijn onveranderd van toepassing.

Gebalanceerd vs. ongebalanceerd​

Een gebalanceerde boom houdt de dieptes ongeveer gelijk; ongebalanceerde bomen kunnen nog steeds sneller zoeken dan lineair, maar zijn minder efficiënt. Willekeurige invoegvolgorde helpt meestal balans te benaderen; invoegen in al-gesorteerde volgorde is het slechtst.

Aanpassen (toevoegen/verwijderen)​

Toevoegen: volg links/rechts tot een lege tak en plaats de waarde. Verwijderen: makkelijk bij een blad of één kind; lastiger bij twee kinderen (diverse strategieën zoals vervangen door opvolger/voorloper of herbouwen van subboom).