Quelqu'un peut-il me donner un exemple de situation dans laquelle une structure Deque data est nécessaire?
Note - S'il vous plaît, n'expliquez pas ce qu'est une deque
?
Un Deque est une file d'attente à deux extrémités, permettant l'insertion et la suppression à partir des deux extrémités.
Dans un scénario réel, nous pouvons l’attacher à une ligne d’achat de billets. Cela fonctionne comme une file d’attente, mais il arrive parfois que des personnes aient acheté le billet et qu’elles reviennent soudainement pour demander quelque chose en face de la file d’attente. Dans ce scénario, ils ont déjà acheté le billet et ont donc le privilège de demander toute autre requête. Donc, dans ce genre de scénario, nous avons besoin d’une structure de données où, selon les besoins, nous ajoutons des données de face. Et dans le même scénario, l'utilisateur peut également quitter la file d'attente par l'arrière.
Donc, il suit complètement la structure de données de Deque.
Lors de la modélisation de tout type de ligne d’attente réelle: les entités (bits, personnes, voitures, mots, particules, etc.) arrivent avec une certaine fréquence à la fin de la ligne et sont desservies à une fréquence différente au début de la ligne. En attendant, certaines entités peuvent décider de quitter la ligne, etc., etc. Le fait est que vous avez besoin d'un "accès rapide" pour insérer/supprimer aux deux extrémités de la ligne, d'où un deque.
Un exemple où un deque peut être utilisé est l'algorithme de planification de travaux A-Steal. Cet algorithme implémente la planification des tâches pour plusieurs processeurs. Un deque séparé avec les threads à exécuter est conservé pour chaque processeur. Pour exécuter le thread suivant, le processeur extrait le premier élément du deque (en utilisant l'opération de retrait "Supprimer le premier élément"). Si le fil actuel est une fourche, il est replacé à l'avant du deque ("insérer un élément à l'avant") et un nouveau fil est exécuté. Lorsque l'un des processeurs a fini d'exécuter ses propres threads (c'est-à-dire que son deque est vide), il peut "voler" un thread sur un autre processeur: il récupère le dernier élément du deque d'un autre processeur ("remove last element") et exécute il.
Dans le récent CLR via C # book Richter décrit les améliorations apportées à ThreadPool dans .Net 4.0. Cela vaut vraiment la peine d'être lu, en particulier sur le vol de travail. L'algorithme décrit par Richter ressemble beaucoup à l'exemple de Wikipedia, donc je soupçonne que Deque y est également utilisé.
http://en.wikipedia.org/wiki/Deque indique qu'il existe des algorithmes de planification de travaux qui utilisent deques. La page wikipedia allemande (http://de.wikipedia.org/wiki/Deque) mentionne les algorithmes de correspondance de modèles et la mise en œuvre de machines à états finis non déterministes comme cas d'utilisation de deques.
Une "file d'attente" peut être implémentée en utilisant l'une des deux structures de données
En règle générale, un deque est utile pour la mise en file d'attente prioritaire. L'analyse de la file d'attente est nettement plus rapide avec un deque que la liste chaînée.
Une deque peut modéliser une gare où les voitures peuvent entrer et sortir du côté gauche ou droit d'une ligne, mais seules les voitures situées aux extrémités peuvent entrer et sortir. C’est parce que les voitures à l’intérieur ne peuvent pas heurter les voitures à l’extérieur pour partir, elles doivent donc attendre.
Il existe un exemple d'utilisation pratique lors de l'enchaînement d'itérateurs. Je l'ai utilisé pour implémenter un itérateur extensible :
import Java.util.Deque;
import Java.util.Iterator;
import Java.util.concurrent.ConcurrentLinkedDeque;
public class ExtendableIterator<T> implements Iterator<T> {
public Deque<Iterator<T>> its = new ConcurrentLinkedDeque<Iterator<T>>();
public ExtendableIterator() {
}
public ExtendableIterator(Iterator<T> it) {
this();
this.extend(it);
}
@Override
public boolean hasNext() {
// this is true since we never hold empty iterators
return !its.isEmpty() && its.peekLast().hasNext();
}
@Override
public T next() {
T next = its.peekFirst().next();
if (!its.peekFirst().hasNext()) {
its.removeFirst();
}
return next;
}
public void extend(Iterator<T> it) {
if (it.hasNext()) {
its.addLast(it);
}
}
}