Où utiliserais-je généralement un Deque dans un logiciel de production?

21

Je sais assez bien où utiliser les piles, les files d'attente et les arbres dans les applications logicielles, mais je n'ai jamais utilisé de Deque (file d'attente à double extrémité) auparavant. Où les rencontrerais-je généralement dans la nature? Serait-ce aux mêmes endroits qu'une file d'attente mais avec des gribbilies supplémentaires?

Ingénieur du monde
la source
semble qu'il y ait une certaine confusion dans ce fil. Sur Internet, "deque" est une file d'attente à double extrémité (wikipedia mentionne l'implémentation d'une liste liée). Cependant en C ++ STL, "std :: deque" est une structure de type tableau implémentée comme un tableau de blocs de données. Il offre un accès aléatoire, similaire à std :: vector, mais sa capacité de redimensionnement est plus proche de celle de std :: list car au fur et à mesure que des données sont ajoutées, il ajoute des blocs et ne réalloue pas et ne déplace pas les données existantes.
DXM
1
@DXM: un deque STL est cependant toujours une file d'attente à double extrémité et fournit des opérations plus rapides aux extrémités (selon la mise en œuvre). Le fait qu'il offre également un accès au milieu ne rend pas son opération principale moins semblable à une file d'attente.
gbjbaanb
@gbjbaanb: Tout ce que je dis, c'est que si vous regardez les interfaces publiques de 3 classes: std :: vector, std :: list (ou std :: queue) et std :: deque, vous verrez que std :: vector et std :: deque ont une interface publique identique et des capacités identiques (std :: deque est légèrement plus flexible au détriment d'une plus grande empreinte mémoire). std :: list et std :: queue d'autre part se comportent plus comme leurs homologues CS, liste liée et file d'attente respectivement. CS deque! = Std :: deque
DXM
Je trouve cette réponse plus pratique par shiv.mymail - stackoverflow.com/questions/3880254/…
roottraveller

Réponses:

21

Une façon d'utiliser un deque consiste à «vieillir» les éléments. Il est généralement utilisé comme fonction d'annulation ou d'historique. Une nouvelle action est insérée dans la deque. Les éléments les plus anciens sont à l'avant. Une limite sur la taille de la déque force les éléments à l'avant à être retirés à un moment donné lorsque de nouveaux éléments sont insérés (vieillissant les plus anciens). Il fournit ensuite un moyen rapide d'accéder aux deux extrémités de la structure, car vous connaissez instantanément les éléments les plus anciens et les plus récents pour supprimer le front et valider l'action la plus ancienne en O (1) ou annuler en O (1).

jmq
la source
Je ne pense pas que les deques soient utilisés / nécessaires ici. Une pile simple (peut-être limitée en taille) suffit.
Konrad Rudolph
2
@Konrad Comment vieillissez-vous les objets dans une pile simple? (c'est-à-dire comment supprimer les commandes "trop ​​anciennes"?)
Andres F.
@AndresF. L'âge est-il indépendant de la taille de la pile? Si oui, alors je n'ai jamais entendu parler de cette structure de données. Sinon, c'est simplement une pile de taille fixe qui peut être implémentée en termes de deque, ou simplement en postulant une structure de données plus simple appelée pile de taille fixe.
Konrad Rudolph
Les deques sont donc utiles après tout;) Jamais entendu parler d'une pile de taille fixe (dans le sens où vous l'entendez, de supprimer l'élément le plus ancien). Cela a du sens, mais ce n'est pas ce que l'on entend généralement par "pile", et il reste à voir si c'est plus simple :)
Andres F.
Cela a été publié dans les commentaires de la question d'origine: en.wikipedia.org/wiki/Double-ended_queue Ce n'est qu'une file d'attente à double extrémité. Je l'ai utilisé dans la pratique de la manière que j'ai décrite ci-dessus (c'est pourquoi je l'ai posté). Dans une vraie pile, les seules opérations que vous devriez avoir sont push, pop, top et peek (nous pourrions en discuter d'autres, mais c'est généralement ça). Vous ne devriez avoir aucune connaissance de ce qui se trouve au bas de la pile ni même comment accéder au fond. Dans une «pile de taille fixe», vous générez simplement un débordement de pile au lieu de vieillir les anciens éléments lorsque vous la remplissez.
jmq
1

Excellente question. Je ne me souviens pas de notre cours CS 102 mentionnant une seule application pour la file d'attente double.

À ce jour, la seule application que je connaisse est le planificateur de vol de travail mentionné dans l'article Wikipedia .

Il fonctionne essentiellement comme suit:

Dans un modèle procédural normal à un seul thread, chaque appel de fonction envoie un enregistrement d'activation sur une soi-disant pile d'appels . Un enregistrement d'activation contient les variables locales et les paramètres de cet appel. Une fois l'appel à la méthode terminé («retourne»), le dernier enregistrement d'activation est extrait de la pile d'appels.

Ceci est particulièrement important car c'est ainsi que la récursivité est implémentée: la structure de la récursivité est représentée dans l'état actuel de la pile d'appels.

Lors de la parallélisation d'un algorithme récursif, nous pouvons exploiter cette propriété en remplaçant la pile d'appels par une file d'attente d'appels. Chaque thread du calcul obtient sa propre file d'attente d'appels et pousse et affiche les enregistrements d'activation comme dans une exécution séquentielle.

Mais une fois qu'un thread a terminé son travail (= sa file d'attente d'appels est vide), il vole le travail d'un autre thread en supprimant un enregistrement d'activation de la file d'attente d'appels de ce thread en le supprimant de la «mauvaise» extrémité.

Fondamentalement, la file d'attente des appels agit comme deux piles d'appels qui desservent désormais deux threads.

Konrad Rudolph
la source
Avez-vous une source pour cela? Ça semble intéressant.
kyjelly90210
1
@ Richard1987 L'article de Wikipedia cite l'article original. Plusieurs implémentations existent, par exemple dans l' implémentation de vol de travail d' extension parallèle GNU c ++ stdlib (mais le code est horrible à lire) ou une implémentation parallèle de diviser et conquérir généralisée par la vôtre vraiment (mais cette dernière utilise un style de programmation très idiomatique particulier à la bibliothèque et donc difficile à lire)
Konrad Rudolph