Voici une description de la structure de données: p>
Il fonctionne comme une carte régulière avec Par exemple: P>
La deuxième fois que j'appelle la méthode code> code> doit être une opération beaucoup plus rapide, car la structure de la carte n'a pas beaucoup changé. Notez que la carte ne doit pas nécessairement maintenir l'ordre trié entre les appels vers Je comprends que cela pourrait ne pas être possible, mais j'espère que o (1) Alors, quelle est la conception de cette structure de données? P>
Alhough J'aurais aimé entendre la réponse à l'affaire Général ci-dessus, mon cas d'utilisation est devenu plus spécifique: je n'ai pas besoin de tout ce qui est trié; Juste les meilleurs éléments K. P>
Merci! P> obtenez code>,
mettre code> et
supprimer des méthodes code>, mais a un
trier code> méthode qui peut être appelée à trier la carte. Cependant, la carte se souvient de sa structure triée, les appels ultérieurs à trier peuvent être beaucoup plus rapides (si la structure ne change pas trop entre les appels vers
trier code>). p>
Mettez code> Méthode 1 000 000 fois.
LI>
trier code>.
li>
Mettez la méthode code> 100 fois plus.
li>
trier code>.
li>
ul>
Trier code>. P>
obtenir code>,
mettre code> et
supprimer code> Opérations . Quelque chose comme Treemap assure garantie O (journal (n)) Coût de temps pour ces opérations, mais maintient toujours une commande triée (no
trier code> méthode). p>
6 Réponses :
Je ne suis pas au courant d'une classification de la structure de données avec ce comportement exact, du moins pas dans des collections Java (ou de la classe de structures de données non linéaires). Peut-être que vous pouvez la mettre en œuvre, et il sera désormais connu comme le rudigermap code>. P>
Une sorte de hashmap hybride / Treemap peut-être? Les insertions entrent dans le hashmap, trichent puis transfèrent les éléments HASHMAP dans le TREEMAP. Je ne sais pas comment vous obtiendriez O (1) pour les déménagements aussi bien que ... hmmm ..
Je ne sais pas s'il y a un nom, mais vous pourriez stocker l'index actuel de chaque article sur le hachage. P>
C'est-à-dire que vous avez un Lorsque vous Lorsque vous Lorsque vous Lorsque vous hashmap
Mettez code>, ajoutez à la queue ou à la tête de la liste et insérez-le dans le hachoir avec vos données et l'index de l'insertion. Ceci est
O (1) code>. P>
Obtenez CODE>, tirez-le de la HASHMAP et ignorez l'index. Ceci est
O (1) code>. P>
Supprimer CODE>, vous tirez de la carte. Prenez l'index et supprimez également de la liste. Ceci est
O (1) code> p>
Trier code>, triez simplement la liste. Soit mettre à jour les index sur la carte pendant le tri ou la mise à jour après la fin du tri complet. Cela n'affecte pas le tri
O (nlgn) code>, car il s'agit d'une étape linéaire.
O (nlgn + n) == O (nlgn) code> p>
Je ne pense pas supprimer code> est
o (1) code> ... lorsque vous appelez
supprimer code>, il supprime de la liste et décède les index .
Juste parce que vous supprimer code> un objet à partir d'une liste triée ne signifie pas que ce n'est toujours pas trié ... c'est-à-dire. [3, 5, 6]. Il n'y a pas de 4 dans la liste, mais il est toujours trié correctement ... Donc, le tri ne devrait donc se produire après que le
mettre code>.
pour "o (1) obtenir, mettre et supprimer des opérations" Vous avez essentiellement besoin d'une recherche O (1) O (1), ce qui implique une fonction de hachage (comme vous le savez), mais les exigences d'une bonne fonction de hachage brisent souvent l'exigence de être facilement trié. (Si vous aviez une table de hachage dans laquelle des valeurs adjacentes sont mappées sur le même seau, elle serait dégénérée à O (n) sur de nombreuses données communes, ce qui est un cas pire que vous souhaitez généralement une fonction de hachage à éviter.) P>
Je peux penser à comment vous procurer 90% du chemin. Configurez une hache à côté d'un indice parallèle trié. L'index a une partie propre (commandée) et une partie sale (non ordonnée). L'index planerait les clés des valeurs (ou des références aux valeurs stockées dans la haquetable - selon laquelle vous vous convient en termes de performances ou d'utilisation de la mémoire). Lorsque vous ajoutez à la HASHTABLE, la nouvelle entrée est poussée à l'arrière de la liste sale. Lorsque vous retirez de la haquetable, l'entrée est annulée / retirée des parties propres et sales de l'index. Vous pouvez trier l'index, qui trie les entrées sales uniquement, puis la fusionne dans la partie "propre" de l'index déjà triée. Et évidemment, vous pouvez itérer sur l'indice. P>
Autant que je puisse le voir, cela vous donne le O (1) partout partout, sauf sur la mise en évidence et reste assez simple à mettre en œuvre avec des conteneurs standard (au moins comme prévu par C ++, Java ou Python). Il vous donne également la condition «deuxième tri est moins cher» en ne nécessitant que pour trier les entrées d'index sale, puis vous laisser faire une (n) fusionner. Le coût de tout cela est évidemment une mémoire supplémentaire pour l'index et l'indirection supplémentaire lors de l'utilisation. P>
Vous pouvez également obtenir O (1) sur le Supprimer également, en faisant la saisie de la haquetable, citons une liaison à l'emplacement correspondant de l'index.
Les versions récentes de Python (2.7, 3.1) ont des "dictionnaires commandés" qui ressemblent à ce que vous décrivez. P>
Le "Dictionnaire commandé" de Python officiel est inspiré par les précédentes implémentations tiers, comme décrit dans le PEP 372 . P>
Références: P>
CommandéDict conserve des entrées dans l'ordre d'insertion, pas un ordre de tri des clés naturels.
Vrai, mais il est triable, comme décrit dans la documentation Python. Cela semble être un ajustement assez raisonnable à la description de la question.
Qu'est-ce que vous envisagez est une haquetable avec des pointeurs dans les entrées à la prochaine entrée dans la commande triée. C'est beaucoup comme le LinkedHashMap dans Java, sauf que les liens suivent un ordre de tri plutôt que l'ordre d'insertion. Vous pouvez réellement mettre en œuvre cela totalement en enveloppant une liaison LinkedHashMap et que la mise en oeuvre de transfert de tri les entrées du LinkedHashMap dans un Treemap, puis de nouveau dans une liaison LinkedHashMap.
Voici une implémentation qui trie les entrées dans une liste de matrices plutôt que de transférer à une carte d'arbre. Je pense que l'algorithme de tri utilisé par Collection.Sort fera un bon travail de fusion des nouvelles entrées dans la partie déjà triée. P>
public class SortaSortedMap<K extends Comparable<K>,V> implements Map<K,V> { private LinkedHashMap<K,V> innerMap; public SortaSortedMap() { this.innerMap = new LinkedHashMap<K,V>(); } public SortaSortedMap(Map<K,V> map) { this.innerMap = new LinkedHashMap<K,V>(map); } public Collection<V> values() { return innerMap.values(); } public int size() { return innerMap.size(); } public V remove(Object key) { return innerMap.remove(key); } public V put(K key, V value) { return innerMap.put(key, value); } public Set<K> keySet() { return innerMap.keySet(); } public boolean isEmpty() { return innerMap.isEmpty(); } public Set<Entry<K, V>> entrySet() { return innerMap.entrySet(); } public boolean containsKey(Object key) { return innerMap.containsKey(key); } public V get(Object key) { return innerMap.get(key); } public boolean containsValue(Object value) { return innerMap.containsValue(value); } public void clear() { innerMap.clear(); } public void putAll(Map<? extends K, ? extends V> m) { innerMap.putAll(m); } public void sort() { List<Map.Entry<K,V>> entries = new ArrayList<Map.Entry<K,V>>(innerMap.entrySet()); Collections.sort(entries, new KeyComparator()); LinkedHashMap<K,V> newMap = new LinkedHashMap<K,V>(); for (Map.Entry<K,V> e: entries) { newMap.put(e.getKey(), e.getValue()); } innerMap = newMap; } private class KeyComparator implements Comparator<Map.Entry<K,V>> { public int compare(Entry<K, V> o1, Entry<K, V> o2) { return o1.getKey().compareTo(o2.getKey()); } } }
Pourquoi avez-vous besoin exactement d'une fonction de tri ()?
Que voulez-vous peut-être et besoin d'un arbre noir rouge. P>
http://fr.wikipedia.org/wiki/red-black_tree p>
Ces arbres sont automatiquement em> trier votre entrée par un comparateur que vous donnez. Ils sont complexes, mais ont d'excellentes caractéristiques O (n). Couple de vos entrées d'arbres comme clé avec un hachage
Carte comme dictionnaire et vous obtenez votre DataStructure. P>
en Java, il est implémenté comme Treemap en tant qu'instance de type. p>