Una pregunta similar se hizo anteriormente allí , pero la pregunta aquí es lo contrario, usando dos colas como una pila. La pregunta...
Habida cuenta de dos colas con sus operaciones estándar ( enqueue
, dequeue
, isempty
, size
), implementar una pila con sus operaciones estándar ( pop
, push
, isempty
, size
).
Debería haber dos versiones de la solución.
- Versión A : la pila debe ser eficiente al empujar un elemento; y
- Versión B : la pila debe ser eficiente cuando aparece un elemento.
Estoy interesado en el algoritmo más que cualquier implementación de lenguaje específico. Sin embargo, agradezco las soluciones expresadas en idiomas que conozco (Java,C#,pitón,vb,javascript,php)
algorithm
data-structures
stack
TechTravelThink
fuente
fuente
Pop
funciona en $ O (1) $ yPush
funciona en $ O (\ sqrt {n}) $ tiempo amortizado.Respuestas:
Versión A (empuje eficiente):
Versión B (pop eficiente):
fuente
La forma más fácil (y quizás la única) de hacer esto es empujando nuevos elementos a la cola vacía, y luego retirando al otro y pasando a la cola previamente vacía. De esta manera, lo último siempre está al frente de la cola. Esta sería la versión B, para la versión A simplemente invierte el proceso eliminando los elementos en la segunda cola, excepto la última.
Paso 0:
Paso 1:
Paso 2:
Paso 3:
fuente
Podemos hacer esto con una cola:
empujar:
n
es el número de elementos en la cola, elimine e inserten-1
tiempos de elementos .popular:
.
Implementación de muestra:
fuente
fuente
¿Podemos usar una sola cola para implementar una pila? Puedo usar dos colas, pero considerar una sola cola sería más eficiente. Aquí está el código:
fuente
fuente
Aquí está mi respuesta, donde el 'pop' es ineficiente. Parece que todos los algoritmos que vienen inmediatamente a la mente tienen N complejidad, donde N es el tamaño de la lista: si eliges trabajar en el 'pop' o trabajar en el 'push'
El algoritmo en el que las listas se intercambian hacia atrás y el cuarto puede ser mejor, ya que no es necesario un cálculo de tamaño, aunque aún necesita hacer un bucle y comparar con vacío.
puede probar que este algoritmo no se puede escribir más rápido que N al observar que la información sobre el último elemento en una cola solo está disponible al conocer el tamaño de la cola, y que debe destruir los datos para llegar a ese elemento, por lo tanto, la segunda cola .
La única forma de hacer esto más rápido es no usar colas en primer lugar.
fuente
Aquí está mi solución que funciona para O (1) en el caso promedio. Hay dos colas:
in
yout
. Ver pseudocódigo a continuación:fuente
Como se ha mencionado, ¿no sería suficiente una sola cola? Probablemente sea menos práctico, pero es un poco más elegante.
fuente
Aquí hay un pseudocódigo simple, push es O (n), pop / peek es O (1):
fuente
Deje que S1 y S2 sean las dos pilas que se utilizarán en la implementación de colas.
Nos aseguramos de que una cola esté vacía siempre.
Operación de inserción: cualquiera que sea la cola que no esté vacía, inserte el elemento en ella.
Push (struct Stack *S, int data) { if(isEmptyQueue(S->Q1) EnQueue(S->Q2, data); else EnQueue(S->Q1, data); }
Complejidad de tiempo: O (1)
Operación pop: transfiera elementos n-1 a otra cola y elimine el último de la cola para realizar la operación pop.
``
Complejidad de tiempo: tiempo de ejecución de pop La operación es O (n) ya que cada vez que se llama pop, estamos transfiriendo todos los elementos de una cola a otra.
fuente
fuente
fuente
Aquí hay una solución más:
para PUSH: -Agregue el primer elemento en la cola 1. -Al agregar el segundo elemento y así sucesivamente, coloque primero el elemento en la cola 2 y luego copie todo el elemento de la cola 1 a la cola2. -para POP simplemente elimine el elemento de la cola desde que insertó el último elemento.
Entonces,
}}
Hay un problema, no puedo entender, ¿cómo cambiar el nombre de las colas?
fuente
fuente
Código Python usando solo una cola
fuente
Aquí está el código de trabajo completo en C #:
Se ha implementado con Single Queue,
empujar:
popular:
fuente
Aquí hay una solución muy simple que usa una cola y brinda funcionalidades como Stack.
Entonces, en la clase anterior llamada "CustomStack", lo que estoy haciendo es verificar si la cola está vacía, si está vacía, inserte una y, a partir de ese momento, inserte y luego elimine la inserción. Por esta lógica, primero vendrá el último. Ejemplo: en la cola inserté 1 y ahora trato de insertar 2. La segunda vez, elimine 1 y vuelva a insertar para que quede en orden inverso.
Gracias.
fuente
A continuación se muestra una solución Java muy simple que admite la operación de inserción eficiente.
Algoritmo
Declara dos colas q1 y q2.
Operación de inserción: coloque el elemento en cola en la cola q1.
Operación emergente: asegúrese de que la cola q2 no esté vacía. Si está vacío, elimine todos los elementos de q1 excepto el último elemento y póngalo en cola a q2 uno por uno. Elimine el último elemento de q1 y guárdelo como el elemento emergente. Intercambie las colas q1 y q2. Devuelve el elemento emergente almacenado.
Operación Peek: asegúrese de que la cola q2 no esté vacía. Si está vacío, elimine todos los elementos de q1 excepto el último elemento y póngalo en cola a q2 uno por uno. Separe el último elemento de q1 y guárdelo como el elemento asomado. Vuelva a ponerla en la cola q2 e intercambie las colas q1 y q2. Devuelve el elemento peeked almacenado.
A continuación se muestra el código para el algoritmo anterior:
fuente
Aquí está mi solución ...
Concept_Behind ::
push(struct Stack* S,int data)
:: Esta función pone en cola el primer elemento en Q1 y descansa en Q2pop(struct Stack* S)
:: si Q2 no está vacío, transfiere todos los elementos a Q1 y devuelve el último elemento en Q2 más (lo que significa que Q2 está vacío) transfiere todos los elementos a Q2 y devuelve el último elemento en Q1Efficiency_Behind ::
push(struct Stack*S,int data)
:: O (1) // desde una sola cola por datospop(struct Stack* S)
:: O (n) // ya que transfiere los peores datos n-1 por pop.fuente
fuente
fuente