Une question similaire a déjà été posée il , mais la question est ici l'inverse de celui - ci, en utilisant deux files d' attente comme une pile. La question...
Compte tenu de deux files d' attente avec leurs opérations standard ( enqueue
, dequeue
, isempty
, size
), mettre en œuvre une pile avec ses opérations standard ( pop
, push
, isempty
, size
).
Il devrait y avoir deux versions de la solution.
- Version A : La pile doit être efficace lors de la poussée d'un élément; et
- Version B : La pile doit être efficace lors de l'éclatement d'un élément.
Je suis plus intéressé par l'algorithme que par toute implémentation de langage spécifique. Cependant, je salue les solutions exprimées dans des langues que je connais (Java,c #,python,vb,javascript,php).
algorithm
data-structures
stack
TechVoyage
la source
la source
Pop
fonctionne en $ O (1) $ etPush
fonctionne en $ O (\ sqrt {n}) $ temps amorti.Réponses:
Version A (push efficace):
Version B (pop efficace):
la source
Le moyen le plus simple (et peut-être le seul) de le faire est de pousser de nouveaux éléments dans la file d'attente vide, puis de retirer l'autre de la file d'attente et de mettre en file d'attente la file d'attente précédemment vide. De cette façon, le dernier est toujours en tête de la file d'attente. Ce serait la version B, pour la version A, il vous suffit d'inverser le processus en retirant les éléments de la file d'attente dans la deuxième file d'attente à l'exception de la dernière.
Étape 0:
Étape 1:
Étape 2:
Étape 3:
la source
Nous pouvons le faire avec une seule file d'attente:
pousser:
n
est le nombre d'éléments dans la file d'attente, supprimez et insérez lesn-1
temps d' élément .pop:
.
Exemple d'implémentation:
la source
la source
Pouvons-nous utiliser une seule file d'attente pour implémenter une pile? Je peux utiliser deux files d'attente, mais considérer une seule file d'attente serait plus efficace. Voici le code:
la source
la source
Voici ma réponse - là où le «pop» est inefficace. Il semble que tous les algorithmes qui viennent immédiatement à l'esprit ont N complexité, où N est la taille de la liste: que vous choisissiez de travailler sur le 'pop' ou de travailler sur le 'push'
L'algorithme où les listes sont échangées en arrière et en quatrième peut être meilleur, car un calcul de taille n'est pas nécessaire, bien que vous ayez toujours besoin de boucler et de comparer avec vide.
vous pouvez prouver que cet algorithme ne peut pas être écrit plus rapidement que N en notant que les informations sur le dernier élément d'une file d'attente ne sont disponibles qu'en connaissant la taille de la file d'attente, et que vous devez détruire les données pour accéder à cet élément, d'où la 2ème file d'attente .
La seule façon de rendre cela plus rapide est de ne pas utiliser les files d'attente en premier lieu.
la source
Voici ma solution qui fonctionne pour O (1) dans le cas moyen. Il y a deux files d'attente:
in
etout
. Voir le pseudocode ci-dessous:la source
Comme cela a été mentionné, une seule file d'attente ne ferait-elle pas l'affaire? C'est probablement moins pratique mais un peu plus astucieux.
la source
Voici un pseudo-code simple, push est O (n), pop / peek est O (1):
la source
Soit S1 et S2 les deux piles à utiliser dans l'implémentation des files d'attente.
Nous nous assurons qu'une file d'attente est toujours vide.
Opération push: quelle que soit la file d'attente non vide, insérez-y l'élément.
Push (struct Stack *S, int data) { if(isEmptyQueue(S->Q1) EnQueue(S->Q2, data); else EnQueue(S->Q1, data); }
Complexité temporelle: O (1)
Opération Pop: Transférez n-1 éléments vers une autre file d'attente et supprimez le dernier de la file d'attente pour effectuer une opération Pop.
»
Complexité temporelle: le temps d'exécution de l'opération pop est O (n) car chaque fois que pop est appelé, nous transférons tous les éléments d'une file d'attente à l'autre.
la source
la source
la source
Voici une autre solution:
pour PUSH: -Ajoutez le premier élément dans la file d'attente 1. -Lors de l'ajout du deuxième élément et ainsi de suite, mettez d'abord l'élément en file d'attente dans la file d'attente 2, puis copiez tout l'élément de la file d'attente 1 dans la file d'attente2. -Pour POP, retirez simplement l'élément de la file d'attente de l'insertion du dernier élément.
Alors,
}}
Il y a un problème, je ne suis pas en mesure de comprendre, comment renommer les files d'attente ???
la source
la source
Code Python utilisant une seule file d'attente
la source
voici le code de travail complet en c #:
Il a été implémenté avec Single Queue,
pousser:
pop:
la source
Voici une solution très simple qui utilise une file d'attente et offre des fonctionnalités telles que Stack.
Donc, dans la classe ci-dessus nommée "CustomStack", ce que je fais est juste de vérifier que la file d'attente est vide, si elle est vide, insérez-en une et à partir de là, insérez puis supprimez l'insertion. Par cette logique, le premier viendra en dernier. Exemple: Dans la file d'attente, j'ai inséré 1 et j'essaie maintenant d'insérer 2. Deuxième fois, retirez 1 et insérez à nouveau pour qu'il devienne dans l'ordre inverse.
Je vous remercie.
la source
Voici une solution Java très simple qui prend en charge l'opération push de manière efficace.
Algorithme -
Déclarez deux files d'attente q1 et q2.
Opération push - Mettre l'élément en file d'attente dans la file d'attente q1.
Opération Pop - Assurez-vous que la file d'attente q2 n'est pas vide. S'il est vide, retirez tous les éléments de q1 à l'exception du dernier élément et placez-le dans q2 un par un. Retirez le dernier élément de q1 et stockez-le comme élément popped. Permutez les files d'attente q1 et q2. Renvoie l'élément popped stocké.
Opération Peek - Assurez-vous que la file d'attente q2 n'est pas vide. S'il est vide, retirez tous les éléments de q1 à l'exception du dernier élément et placez-le dans q2 un par un. Retirez le dernier élément de q1 et stockez-le comme élément examiné. Remettez-le en file d'attente dans la file d'attente q2 et échangez les files d'attente q1 et q2. Renvoie l'élément consulté stocké.
Ci-dessous le code de l'algorithme ci-dessus -
la source
Voici ma solution ...
Concept_Behind ::
push(struct Stack* S,int data)
:: Cette fonction met en file d'attente le premier élément de Q1 et reste dans Q2pop(struct Stack* S)
:: si Q2 n'est pas vide, transfère tous les éléments dans Q1 et retourne le dernier élément de Q2 sinon (ce qui signifie que Q2 est vide) transfère tous les éléments dans Q2 et renvoie le dernier élément de Q1Efficiency_Behind ::
push(struct Stack*S,int data)
:: O (1) // depuis une seule mise en file d'attente par donnéespop(struct Stack* S)
:: O (n) // car transfère les pires n-1 données par pop.la source
la source
la source