J'essaie de mettre en œuvre une liste liée à C. Une implémentation commune que vous voyez flottant autour d'Internet est quelque chose comme avec des méthodes telles que P> Node cons(int head, Node tail) {
Node y;
y.head = head;
y.tail = malloc(sizeof(Node));
*y.tail = tail;
}
8 Réponses :
Ajout très rapide à une liste liée? Un Rope (non limité aux chaînes avec de petites modifications) vous permettrait d'allouer de la mémoire lot (amélioration de la performance) tout en ne pénalisant à la fin de la liste. P>
Les listes liées ne fonctionnent pas bien. +1 Pour suggérer la seule réponse raisonnable ici - utilisez une autre structure de données! (De préférence quelque chose comme STD :: DEQUE ou STD :: Vecteur!)
@Billy, je ne comprends pas pourquoi votre commentaire a été voté depuis que la question est spécifiquement sur C B> et que vous préconisez une solution C ++.
@Jeremy vous pouvez mettre en œuvre quelque chose comme un vecteur en C
La corde est essentiellement un arbre binaire. Pour certaines opérations, il est plus lent qu'une liste. Cela peut également impliquer davantage d'allocation de mémoire, en fonction du modèle d'accès.
@Jeremyp: Qu'est-ce que @pete a dit. Les mots "quelque chose comme" font réellement quelque chose :)
Mais mettre en œuvre "quelque chose comme STD :: Vector in C" ne dit rien d'autre que "Utiliser une autre structure de données différente". Quelle est la mise en œuvre de std :: vecteur?
Oui, c'est ... Ceci est appelé comme une piscine mémoire. Semblable à une piscine de fil. Fondamentalement, vous allouez une zone de mémoire au début du programme de type nœud de type. Les pointeurs de cette zone sont stockés dans un tableau. Dans votre fonction inconvénient, tout ce que vous faites est d'obtenir les pointeurs de la matrice. Cela n'améliore pas la vitesse globale, mais si vous avez des allocations de mémoire fréquentes, cela augmentera la réactivité du programme au coût de certains espaces pour le tableau P>
+1. Vous vraiment i> devez pré-allouer l'espace pour le nœud dans les piscines. Les allocations individuelles vous tueront si vous en créez beaucoup d'entre eux.
Oui ... mais pour une liste liée comme celle dont il est montré, cela n'a pas vraiment d'importance: p.
Si vous êtes préoccupé par la fragmentation MALLOC, vous pouvez demander un grand nombre de nœuds de taille et continuer à incrémenter un pointeur de taille de taille de la taille de la taille d'une copie des valeurs de nœud. P>
C'est probablement mieux que les solutions de tableau d'autres suggèrent. Vous devez garder une trace de votre piscine et savoir quand allouer plus, et savoir quand tous les pointeurs ont été retournés.
Quelle opération doit être rapide: insertion, récupération, tout? Il y a toujours un compromis. Votre solution doit-elle être évolutive? La liste liée ne sont pas. P>
Si vous souhaitez / besoin de vous tenir à une liste liée, vous pouvez le stocker dans une gamme de structures comportant un champ indiquant l'index de la prochaine entrée dans la liste liée. L'insertion sera très rapide, sans aucune allocation, l'inconvénient étant que vous devez connaître le nombre d'éléments à l'avance - ou pour réaffecter la table quand il sera plein. p>
Reportez-vous aux " listes liées à l'aide de tableaux de nœuds em>" sous-section de La page Wikipedia sur la liste liée . p>
Je vous suggère d'utiliser la liste de la liste des noyaux Linux: P>
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob ;f=include/linux/list.h p>
(pas d'allocation de mémoire supplémentaire) p>
De nombreux problèmes de performance sont liés à la localité du pointeur et à la répartition de la mémoire. Comme cette implémentation ne met pas en œuvre ces pièces, je ne pense pas que cela soit utile pour Michael Dickens.
git.kernel.org/?p=linux/kernel/git/torvalds/... Il préfère même le premier pointeur pour la prochaine itération. Croyez-moi, cette liste dans le noyau est très optimisée
La mémoire se préoccupe de côté, certaines réflexions sur la création de listes de liaison unique plus rapidement.
Je pense qu'il y a un peu de confusion dans votre code. A son point de vue, une liste liée est la suivante: p> la plupart des implémentations seraient un Les inserts de liste doivent connecter les pointeurs. Pour simplement ajouter le nœud (et ignorer l'ajout de l'ajout de la charge utile) 1 mission si le noeud se passe à la tête ou à la queue d'une liste, et 2 s'il se passe au milieu. Il n'y a pas beaucoup de choses qui peuvent être faites pour se déplacer. P> Les listes de manière occasionnelle utilisent uniquement des structures de nœuds, une insertion de queue nécessite donc une traversée. C'est coûteux. Avoir une structure de la tête spéciale avec la connaissance du premier et du dernier nœud supprime ce coût. P> Les traverses peuvent être apportées plus rapidement en implémentant cela comme une liste de saut ( http://fr.wikipedia.org/wiki/skip_list ). Bien que certains soins doivent être pris pendant l'insertion de nœuds pour optimiser (et vous obtenez plus d'affectations de pointeur lors de l'insertion). p> p> void * code> là pour accrocher la charge utile. Ce n'est pas particulièrement important pour l'instant. P>
Vérifiez également la vitesse de cette liste de liste liée également: P>
http: // Web .Rarchive.org / Web / 20071103112712 / http: //stsdas.stesci.edu/bps/linked_list.html P>
Ceci est une liaison morte.
Si les seules opérations dont vous avez besoin est de pousser, de sauter et d'itération alors au lieu de la liste liée, vous pouvez mettre des éléments dans un tableau. L'élément poussant et popping est juste pour modifier un chiffre (index du premier ou du dernier élément). L'avant et l'arrière de la matrice peuvent être connectés de manière cyclique, des éléments peuvent être poussés librement sans problème que le tableau se termine. P>
Je n'ai jamais vu de noeud déclaré avec un
int. / Code>. Peut-être que vous voulez dire
int ukeload code>? Ideme va pour un
nœud * queue code>. Peut-être que vous voulez dire
noeud * Suivant code>? De plus, avec votre définition actuelle du nœud inconvénients (...), vous avez une inadéquation de type
nœud tête code> étant affectée à
int Head code>. Aucune infraction, mais il semble y avoir des problèmes plus profonds que la performance ...
Mise en œuvre non standard Je suppose ... essentiellement la tête = Data and Tail = Link! Déteste quand certains enseignants essaient de trop simplifier les choses!
@ Ram Bhat - Ne pensez pas que vous puissiez blâmer les enseignants. Il a dit qu'il avait constaté que «flotter sur Internet».
Certains diraient que c'est une éducation informelle: D
merveille où vous avez trouvé que
flottant autour ". Votre fonction des inconvénients n'a même pas de déclaration de retour. Et puisque vous faites copier en valeur pour code> queue "deux fois, les problèmes de performance se trouvent ailleurs, je suppose.
Cela donne un sens en termes de
voiture code> et
CDR code>.
Quelles sont les exigences du conteneur? Est-ce vraiment doit être une liste liée? Quelles opérations sont les plus fréquentes? Quelles opérations ont coûté le plus? La réponse est la suivante: utilisez un tel conteneur qui convient à vos besoins. Vous n'avez pas écrit ce qu'ils sont ... Soyez simplement plus précis, disant «J'ai besoin d'une liste liée rapide» ne suffit pas.
Si vous recherchez une liste de liens qui fournit une traversée plus rapide, consultez les listes de saut.