3

J'ai des exigences spécifiques pour la structure de données à utiliser dans mon programme en Java. Il (Data Structure) devrait être capable de contenir de grandes quantités de données (non fixées), mes opérations principales seraient d'ajouter à la fin, et de supprimer/lire depuis le début (LinkedLists semble bien jusqu'à maintenant). Mais de temps en temps, j'ai aussi besoin de supprimer du milieu et c'est là que LinkedLists sont tellement douloureux. Quelqu'un peut-il me suggérer un moyen de contourner cela? Ou des optimisations à travers lesquelles je peux rendre la suppression moins douloureuse dans LinkedLists?Quelle structure de données? LinkedList ou tout autre en Java?

Merci pour l'aide!

Répondre

2

Vous pouvez essayer d'utiliser la liste chaînée avec un pointeur après chaque élément 10000e afin que vous puissiez réduire le temps de trouver le milieu que vous souhaitez supprimer. voici quelques différentes variantes de liste chaînée: http://experimentgarden.blogspot.com/2009/08/performance-analysis-of-thirty-eight.html

+2

Vous pensez à un skiplist? http://en.wikipedia.org/wiki/Skip_list Les causes ajoutent et suppriment être O (log n) –

+0

ouais j'ai étudié les skiplists par pugh et al, ils semblent être une solution viable –

3

LinkedList tombe vers le bas sur les accès aléatoires. Suppression, sans la recherche d'accès aléatoire, est un temps constant et donc vraiment pas trop mal pour les longues listes.

ArrayList est généralement rapide. Les insertions et les suppressions du milieu sont plus rapides que vous ne le pensez, car les mouvements de mémoire de bloc sont étonnamment rapides. Les retraits et les insertions près du début provoquent le déplacement de toutes les données suivantes vers le haut ou vers le bas.

ArrayDeque est comme ArrayList seulement il utilise un tampon circulaire et a une interface étrange.

Conseil habituel: essayez-le.

+0

@Spedge Bon point. –

4

Un LinkedHashMap peut convenir à votre but Vous souhaitez utiliser un itérateur pour tirer des choses de la avant et rechercher l'entrée par clé lorsque vous avez besoin pour accéder au milieu de la liste

0

LinkedHashMap est probablement la voie à aller. Idéal pour l'itération, opérations de deque, et la recherche dans le milieu. Cependant, cela vous coûtera plus cher en mémoire, car vous devrez gérer un jeu de clés au-dessus de votre collection de base. De plus, je pense que cela laissera des «espaces» dans les espaces que vous avez supprimés, conduisant à un ensemble de clés non consécutives (ne devrait pas affecter l'itération, cependant).

Édition: Aha! Je sais ce dont vous avez besoin: A LinkedMultiSet! Tout le bénéfice d'un LinkedHashMap, mais sans le jeu de clés superflus. Cependant, c'est un peu plus complexe à utiliser.

0

D'abord vous devez considérer si vous allez supprimer du centre de la liste souvent par rapport à la longueur de la liste. Si votre liste contient N, mais que vous supprimez moins souvent 1/N, ne vous inquiétez pas. Utilisez LinkedList ou ArrayDeque comme vous préférez. (Si vos listes sont parfois énormes et puis rétrécissent, mais sont généralement petites, LinkedList est préférable car il est facile de récupérer la mémoire, sinon, ArrayDeque n'a pas besoin d'objets supplémentaires, donc c'est un peu plus rapide et plus compact - sauf le sous-jacent tableau ne rétrécit)

Si, d'autre part, vous supprimez un peu plus souvent que 1/N, alors vous devriez envisager un LinkedHashSet, qui maintient une file d'attente de liste chaînée au-dessus d'un ensemble de hachage -. mais est un ensemble, alors gardez à l'esprit que vous ne pouvez pas stocker des éléments en double. Cela a les frais généraux de LinkedList et ArrayDeque mis ensemble, mais si vous faites des suppressions centrales souvent, ça va probablement en valoir la peine.La structure optimale, cependant - si vous avez vraiment besoin de chaque once de vitesse et que vous êtes prêt à passer le temps de codage pour l'obtenir - serait une matrice "redimensionnable" (c'est-à-dire réallouée quand elle était trop petite) avec un tampon circulaire où vous pouvez effacer les éléments du milieu en les mettant à null. (Vous pouvez également réaffecter la mémoire tampon lorsque trop était vide si vous avez un cas d'utilisation perverse alors.) Je ne conseille pas de coder ceci, sauf si vous aimez vraiment coder des structures de données hautes performances ou si vous avez de bonnes preuves que c'est l'un des goulots d'étranglement dans votre code et donc vous en avez vraiment besoin.

Questions connexes