[Multi Plateforme] Listes chainées dynamiques.
Publié : lun. 26/oct./2009 12:54
Qui n'a jamais voulu faire rentrer une liste chainée dans une structure? Ou créer dynamiquement des listes chainées dans son programme?
En tous cas, moi j'en ai souvent eu besoin, alors voilà une solution:
Bon, alors niveau utilisation, voici un exemple:
Petite explication: la liste ne fait que mémoriser des pointeurs mémoires. Ainsi, quand on ajoute un élément, on crée une zone mémoire (peut importe la taille) et on ajoute son adresse dans la liste.
On peut par la suite récupérer le pointeur et y lire ou écrire via des peek et des poke.
L'avantage: on peut faire des listes où chaque élément est d'un type différent (ceci dit, c'est pas conseillé, par ce que pour naviguer dedans après, ca peut être du sport); et surtout on peut faire quelque chose comme ca:
Et donc imbriquer des listes dans d'autres listes, ou dans des tableau (ou n'importe quoi d'autre en fait).
L'inconvénient: Ca peut provoquer des memory leaks, j'ai pas vraiment checké la lib de ce coté là; mais je fais attention quand je l'utilise, faites pareil :þ.
Coté vitesse d'utilisation, y'a surement de l'optimisation à faire, mais le résultat actuel est déjà relativement rapide.
En tous cas, moi j'en ai souvent eu besoin, alors voilà une solution:
Code : Tout sélectionner
#SizeOfInteger = SizeOf(Integer)
Structure Dynamic_Linked_List
*ptr.i
number.i
EndStructure
Procedure DLLCountElement(*this.Dynamic_Linked_List)
ProcedureReturn *this\number
EndProcedure
Procedure DLLSetElement(*this.Dynamic_Linked_List,number.i, *Element)
If number > *this\number
*this\number = number
*this\ptr = ReAllocateMemory(*this\ptr, number * #SizeOfInteger)
EndIf
PokeI(*this\ptr + (number-1) * #SizeOfInteger, *Element)
EndProcedure
Procedure DLLAddElement(*this.Dynamic_Linked_List,*Element)
DLLSetElement(*this,*this\number+1, *Element)
ProcedureReturn *this\number
EndProcedure
Procedure DLLFreeElement(*this.Dynamic_Linked_List,number.i)
If *this\number = 1
*this\number = 0
FreeMemory(PeekI(*this\ptr))
Else
If number <= *this\number
FreeMemory(PeekI(*this\ptr + (number-1) * #SizeOfInteger))
CopyMemory(*this\ptr + #SizeOfInteger*number, *this\ptr + #SizeOfInteger*(number - 1), #SizeOfInteger*(*this\number-number))
*this\number - 1
*this\ptr = ReAllocateMemory(*this\ptr, *this\number * #SizeOfInteger)
EndIf
EndIf
EndProcedure
Procedure DLLGetElement(*this.Dynamic_Linked_List,number.i)
If number <= *this\number
ProcedureReturn PeekI(*this\ptr + (number-1) * #SizeOfInteger)
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure DLLRemoveAll(*this.Dynamic_Linked_List)
Protected loop
For loop = 1 To *this\number
DLLFreeElement(*this,1)
Next loop
*this\number = 0
*this\ptr = ReAllocateMemory(*this\ptr, 1)
EndProcedure
Procedure DLLFreeList(*this.Dynamic_Linked_List)
Protected loop
For loop = 1 To *this\number
DLLFreeElement(*this,1)
Next loop
FreeMemory(*this\ptr)
EndProcedure
Procedure DLLNewlist(*this.Dynamic_Linked_List)
*this\ptr = AllocateMemory(1)
EndProcedure
Code : Tout sélectionner
DLLNewlist(Test.Dynamic_Linked_List)
DLLAddElement(Test,AllocateMemory(SizeOf(byte)))
DLLAddElement(Test,AllocateMemory(SizeOf(byte)))
DLLAddElement(Test,AllocateMemory(SizeOf(byte)))
PokeB(DLLGetElement(Test,3),12)
DLLFreeElement(Test,2)
Debug PeekB(DLLGetElement(Test,2))
Debug DLLCountElement(Test)
DLLFreeElement(Test,2)
Debug DLLCountElement(Test)
DLLFreeList(Test)
On peut par la suite récupérer le pointeur et y lire ou écrire via des peek et des poke.
L'avantage: on peut faire des listes où chaque élément est d'un type différent (ceci dit, c'est pas conseillé, par ce que pour naviguer dedans après, ca peut être du sport); et surtout on peut faire quelque chose comme ca:
Code : Tout sélectionner
Structure test
blabla.s
blibli.l
Listdynamique.Dynamic_Linked_List
EndStructure
Truc.test
DLLNewlist(truc\Listdynamique)
L'inconvénient: Ca peut provoquer des memory leaks, j'ai pas vraiment checké la lib de ce coté là; mais je fais attention quand je l'utilise, faites pareil :þ.
Coté vitesse d'utilisation, y'a surement de l'optimisation à faire, mais le résultat actuel est déjà relativement rapide.