Implementare Stack utilizzando due code


143

Una domanda simile è stata posta prima , ma la domanda qui è il contrario, usando due code come stack. La domanda...

Dati due code con le operazioni standard ( enqueue, dequeue, isempty, size), implementare uno stack con le operazioni standard ( pop, push, isempty, size).

Dovrebbero esserci due versioni della soluzione.

  • Versione A : lo stack dovrebbe essere efficiente quando si spinge un oggetto; e
  • Versione B : lo stack dovrebbe essere efficiente quando si fa scoppiare un oggetto.

Sono interessato all'algoritmo più di qualsiasi implementazione specifica del linguaggio. Tuttavia, accolgo con favore le soluzioni espresse in lingue che conosco (,,,,,).


6
Certo che lo e! CLRS - 10.1-6 ( tinyurl.com/clrs-ex-10-1-6 )
rampion

1
Uno stack, due code offre una soluzione elegante in cui Popfunziona in $ O (1) $ e Pushfunziona in $ O (\ sqrt {n}) $ tempo ammortizzato.
hengxin,

1
@rampion Now è CLRS - 10.1-7. :)
nsane,

Post correlato Questo è un altro problema interessante per implementare lo stack usando solo una coda qui .
RBT il

Risposte:


194

Versione A (spinta efficiente):

  • spingere:
    • accodare in coda1
  • pop:
    • mentre la dimensione della coda1 è maggiore di 1, reindirizza gli elementi dequeued dalla coda1 alla coda2
    • dequeue e restituisce l'ultimo elemento di queue1, quindi cambia i nomi di queue1 e queue2

Versione B (pop efficiente):

  • spingere:
    • accodare in coda2
    • accoda tutti gli elementi della coda1 nella coda2, quindi cambia i nomi di coda1 e coda2
  • pop:
    • deqeue dalla coda1

4
La versione B sembra avere problemi: vuoi dire accodare tutti gli elementi di coda2 in coda1 tranne l'ultimo elemento (quindi cambiare i nomi di q1 e q2)?
Icerman,

Il commento di Icerman ha senso per me. La versione B della risposta richiede una modifica. Non ho i permessi di modifica. Qualcuno potrebbe modificare questa risposta?
eeerahul,

2
@eeerahul: l'ho verificato di nuovo e la risposta è corretta. Nel momento in cui Icerman sembra voler accodare tutti gli elementi della coda2 nella coda1, la coda2 è composta solo dal nuovo elemento, quindi il commento non ha senso.
Svante,

La versione A è corretta? spingere 1, spingere 2, spingere 3, spingere 4. pop 4. spingere 5, spingere 6, spingere 7, spingere 8. pop 8. pop 7. Sembra che l'algoritmo farà scoppiare 3 invece di 7. L'algoritmo sembra proprio acceso prima occhiata perché possiamo forse ragionare come: fondamentalmente farai sempre scoppiare l'ultimo elemento accodato nella coda 1. Ma questo è l'ultimo elemento spinto solo se ti sei messo in coda prima. Se hai saltato più volte in successione, non è necessario che sia vero.
user127.0.0.1

1
@ user127.0.0.1: sembra che tu abbia dimenticato di cambiare le code alla fine di ogni pop. C'è un invariante che dopo ogni push e ogni pop, tutti gli elementi sono nella coda1, mentre la coda2 è vuota.
Svante,

68

Il modo più semplice (e forse unico) per farlo è quello di spingere nuovi elementi nella coda vuota, quindi di dequequantare l'altro e accodarsi nella coda precedentemente vuota. In questo modo l'ultimo è sempre in prima fila. Questa sarebbe la versione B, per la versione A basta invertire il processo rimuovendo gli elementi nella seconda coda, tranne l'ultima.

Step 0:

"Stack"
+---+---+---+---+---+
|   |   |   |   |   |
+---+---+---+---+---+

Queue A                Queue B
+---+---+---+---+---+  +---+---+---+---+---+
|   |   |   |   |   |  |   |   |   |   |   |
+---+---+---+---+---+  +---+---+---+---+---+

Passo 1:

"Stack"
+---+---+---+---+---+
| 1 |   |   |   |   |
+---+---+---+---+---+

Queue A                Queue B
+---+---+---+---+---+  +---+---+---+---+---+
| 1 |   |   |   |   |  |   |   |   |   |   |
+---+---+---+---+---+  +---+---+---+---+---+

Passo 2:

"Stack"
+---+---+---+---+---+
| 2 | 1 |   |   |   |
+---+---+---+---+---+

Queue A                Queue B
+---+---+---+---+---+  +---+---+---+---+---+
|   |   |   |   |   |  | 2 | 1 |   |   |   |
+---+---+---+---+---+  +---+---+---+---+---+

Passaggio 3:

"Stack"
+---+---+---+---+---+
| 3 | 2 | 1 |   |   |
+---+---+---+---+---+

Queue A                Queue B
+---+---+---+---+---+  +---+---+---+---+---+
| 3 | 2 | 1 |   |   |  |   |   |   |   |   |
+---+---+---+---+---+  +---+---+---+---+---+

1
La logica di ciò non ha alcun senso. Passa dal passaggio 2 al passaggio 3. Quando "spingo" 3, come posso rimuovere gli elementi nella coda B in modo da ottenere 3 2 1 nella coda A? Se desesco B per accodare A, posso ottenere solo gli elementi nell'ordine 2, 1. Se poi aggiungo 3, otterrò l'ordine 3, 1, 2. Se metto prima la mia spinta e poi dequeue / accoda, ottengo 1, 2, 3.
Tsurantino,

perché non rendere costosa l'operazione di deque piuttosto che rendere costosa l'operazione di accodamento?
Divij Sehgal,

49

Possiamo farlo con una coda:

spingere:

  1. accoda nuovo elemento.
  2. Se nè il numero di elementi nella coda, quindi rimuovere e inserire i n-1tempi degli elementi .

pop:

  1. dequeue

.

push 1


front                     
+----+----+----+----+----+----+
| 1  |    |    |    |    |    |    insert 1
+----+----+----+----+----+----+


push2

front                     
+----+----+----+----+----+----+
| 1  | 2  |    |    |    |    |    insert 2
+----+----+----+----+----+----+

     front                     
+----+----+----+----+----+----+
|    | 2  |  1 |    |    |    |    remove and insert 1
+----+----+----+----+----+----+




 insert 3


      front                     
+----+----+----+----+----+----+
|    | 2  |  1 |  3 |    |    |    insert 3
+----+----+----+----+----+----+

           front                     
+----+----+----+----+----+----+
|    |    |  1 |  3 |  2 |    |    remove and insert 2
+----+----+----+----+----+----+

                front                     
+----+----+----+----+----+----+
|    |    |    |  3 |  2 |  1 |    remove and insert 1
+----+----+----+----+----+----+

Esempio di implementazione:

int stack_pop (queue_data *q)
{
  return queue_remove (q);
}

void stack_push (queue_data *q, int val)
{
  int old_count = queue_get_element_count (q), i;

  queue_insert (q, val);
  for (i=0; i<old_count; i++)
  {
    queue_insert (q, queue_remove (q));
  }
}

9
import java.util.*;

/**
 *
 * @author Mahmood
 */
public class StackImplUsingQueues {

    Queue<Integer> q1 = new LinkedList<Integer>();
    Queue<Integer> q2 = new LinkedList<Integer>();

    public int pop() {
        if (q1.peek() == null) {
            System.out.println("The stack is empty, nothing to return");
            int i = 0;
            return i;
        } else {
            int pop = q1.remove();
            return pop;
        }
    }

    public void push(int data) {

        if (q1.peek() == null) {
            q1.add(data);
        } else {
            for (int i = q1.size(); i > 0; i--) {
                q2.add(q1.remove());
            }
            q1.add(data);
            for (int j = q2.size(); j > 0; j--) {
                q1.add(q2.remove());
            }

        }
    }

    public static void main(String[] args) {
        StackImplUsingQueues s1 = new StackImplUsingQueues();
        //       Stack s1 = new Stack();
        s1.push(1);
        s1.push(2);
        s1.push(3);
        s1.push(4);
        s1.push(5);
        s1.push(6);
        s1.push(7);
        s1.push(8);
        s1.push(9);
        s1.push(10);
        // s1.push(6);
        System.out.println("1st = " + s1.pop());
        System.out.println("2nd = " + s1.pop());
        System.out.println("3rd = " + s1.pop());
        System.out.println("4th = " + s1.pop());
        System.out.println("5th = " + s1.pop());
        System.out.println("6th = " + s1.pop());
        System.out.println("7th = " + s1.pop());
        System.out.println("8th = " + s1.pop());
        System.out.println("9th = " + s1.pop());
        System.out.println("10th= " + s1.pop());
    }
}

Qualcuno potrebbe spiegare il login dietro il metodo push nel codice sopra? Per quanto ho capito, il primo per il ciclo è rimuovere tutti gli elementi in q2 fino a quando q1 ha un elemento rimanente. Perfavore, correggimi se sbaglio.
Giovanni,

4

Possiamo semplicemente usare una coda per implementare uno stack? Posso usare due code, ma considerare la singola coda sarebbe più efficiente. Ecco il codice:

    public void Push(T val)
    {
        queLower.Enqueue(val);
    }

    public  T Pop()
    {

        if (queLower.Count == 0 )
        {
            Console.Write("Stack is empty!");
            return default(T);

         }
        if (queLower.Count > 0)
        {
            for (int i = 0; i < queLower.Count - 1;i++ )
            {
                queLower.Enqueue(queLower.Dequeue ());
           }
                    }

        return queLower.Dequeue();

    }

Immagino che nel metodo pop, la condizione del ciclo for dovrebbe essere i <queLower.Count - 2 mentre stai inizializzando la variabile i con 0.
vignesh

3
queue<int> q1, q2;
int i = 0;

void push(int v) {
  if( q1.empty() && q2.empty() ) {
     q1.push(v);
     i = 0;
  }
  else {
     if( i == 0 ) {
        while( !q1.empty() ) q2.push(q1.pop());
        q1.push(v);
        i = 1-i;
     }
     else {
        while( !q2.empty() ) q1.push(q2.pop());
        q2.push(v);
        i = 1-i;
     }
  }
}

int pop() {
   if( q1.empty() && q2.empty() ) return -1;
   if( i == 1 ) {
      if( !q1.empty() )
           return q1.pop();
      else if( !q2.empty() )
           return q2.pop();
   }
   else {
      if( !q2.empty() )
           return q2.pop();
      else if( !q1.empty() )
           return q1.pop();
   }
}

2

Ecco la mia risposta - dove il "pop" è inefficiente. Sembra che tutti gli algoritmi che vengono subito in mente abbiano una complessità N, in cui N è la dimensione dell'elenco: se si sceglie di lavorare sul "pop" o se si lavora sul "push"

L'algoritmo in cui gli elenchi vengono scambiati e il quarto può essere migliore, poiché non è necessario un calcolo delle dimensioni, anche se è ancora necessario eseguire il ciclo e il confronto con vuoto.

puoi provare che questo algoritmo non può essere scritto più velocemente di N notando che le informazioni sull'ultimo elemento in una coda sono disponibili solo conoscendo le dimensioni della coda e che devi distruggere i dati per arrivare a quell'elemento, quindi la seconda coda .

L'unico modo per renderlo più veloce è di non utilizzare le code in primo luogo.

from data_structures import queue

class stack(object):
    def __init__(self):
        q1= queue 
        q2= queue #only contains one item at most. a temp var. (bad?)

    def push(self, item):
        q1.enque(item) #just stick it in the first queue.

    #Pop is inefficient
    def pop(self):
        #'spin' the queues until q1 is ready to pop the right value. 
        for N 0 to self.size-1
            q2.enqueue(q1.dequeue)
            q1.enqueue(q2.dequeue)
        return q1.dequeue()

    @property
    def size(self):
        return q1.size + q2.size

    @property
    def isempty(self):
        if self.size > 0:
           return True
        else
           return False

2

Ecco la mia soluzione che funziona per O (1) nel caso medio. Esistono due code: ine out. Vedi il pseudocodice sotto:

PUSH(X) = in.enqueue(X)

POP: X =
  if (out.isEmpty and !in.isEmpty)
    DUMP(in, out)
  return out.dequeue

DUMP(A, B) =
  if (!A.isEmpty)
    x = A.dequeue()
    DUMP(A, B)
    B.enqueue(x)

2
Lì stai usando 2 code e 1 stack per simulare 1 stack!
BeniBela,

Intendi lo stack ricorsivo implicito?
Vladimir Kostyukov il

1

Come è stato menzionato, una sola fila non farebbe il trucco? Probabilmente è meno pratico ma è un po 'più tagliente.

push(x):
enqueue(x)
for(queueSize - 1)
   enqueue(dequeue())

pop(x):
dequeue()

1

Ecco qualche semplice pseudo codice, push è O (n), pop / peek è O (1):

Qpush = Qinstance()
Qpop = Qinstance()

def stack.push(item):
    Qpush.add(item)
    while Qpop.peek() != null: //transfer Qpop into Qpush
        Qpush.add(Qpop.remove()) 
    swap = Qpush
    Qpush = Qpop
    Qpop = swap

def stack.pop():
    return Qpop.remove()

def stack.peek():
    return Qpop.peek()

1

Sia S1 e S2 i due stack da utilizzare nell'implementazione delle code.

struct Stack 
{ struct Queue *Q1;
  struct Queue *Q2;
}

Ci assicuriamo che una coda sia sempre vuota.

Operazione push: qualunque sia la coda non vuota, inserire l'elemento al suo interno.

  • Controllare se la coda Q1 è vuota o meno. Se Q1 è vuoto, accoda l'elemento in esso.
  • Altrimenti EnQueue l'elemento in Q1.

Push (struct Stack *S, int data) { if(isEmptyQueue(S->Q1) EnQueue(S->Q2, data); else EnQueue(S->Q1, data); }

Complessità temporale: O (1)

Operazione pop: trasferisce gli elementi n-1 in un'altra coda ed elimina l'ultimo dalla coda per eseguire l'operazione pop.

  • Se la coda Q1 non è vuota, quindi trasferire n-1 elementi da Q1 a Q2 e quindi, DeQueue l'ultimo elemento di Q1 e restituirlo.
  • Se la coda Q2 non è vuota, quindi trasferire n-1 elementi da Q2 a Q1 e quindi, DeQueue l'ultimo elemento di Q2 e restituirlo.

`

int Pop(struct Stack *S){
int i, size;
if(IsEmptyQueue(S->Q2)) 
{
size=size(S->Q1);
i=0;
while(i<size-1)
{ EnQueue(S->Q2, Dequeue(S->Q1)) ;
  i++;
}
return DeQueue(S->Q1);  
}
else{
size=size(S->Q2);
while(i<size-1)
EnQueue(S->Q1, Dequeue(S->Q2)) ;
i++;
}
return DeQueue(S->Q2);
} }

Complessità temporale: tempo di esecuzione del pop L'operazione è O (n) come ogni volta che viene chiamato pop, stiamo trasferendo tutti gli elementi da una coda all'altra.


1
Q1 = [10, 15, 20, 25, 30]
Q2 = []

exp:
{   
    dequeue n-1 element from Q1 and enqueue into Q2: Q2 == [10, 15, 20, 25]

    now Q1 dequeue gives "30" that inserted last and working as stack
}

swap Q1 and Q2 then GOTO exp

1
import java.util.LinkedList;
import java.util.Queue;

class MyStack {
    Queue<Integer> queue1 = new LinkedList<Integer>();
    Queue<Integer> queue2 = new LinkedList<Integer>();

    // Push element x onto stack.
    public void push(int x) {
        if(isEmpty()){
            queue1.offer(x);
        }else{
            if(queue1.size()>0){
                queue2.offer(x);
                int size = queue1.size();
                while(size>0){
                    queue2.offer(queue1.poll());
                    size--;
                }
            }else if(queue2.size()>0){
                queue1.offer(x);
                int size = queue2.size();
                while(size>0){
                    queue1.offer(queue2.poll());
                    size--;
                }
            }
        }
    }

    // Removes the element on top of the stack.
    public void pop() {
        if(queue1.size()>0){
            queue1.poll();
        }else if(queue2.size()>0){
            queue2.poll();
        }
    }

    // Get the top element. You can make it more perfect just example
    public int top() {
       if(queue1.size()>0){
            return queue1.peek();
        }else if(queue2.size()>0){
            return queue2.peek();
        }
        return 0;
    }

    // Return whether the stack is empty.
    public boolean isEmpty() {
        return queue1.isEmpty() && queue2.isEmpty();
    }
}

0

Ecco un'altra soluzione:

per PUSH: -Aggiungere il primo elemento nella coda 1. -Quando si aggiunge il secondo elemento e così via, accodare prima l'elemento nella coda 2 e quindi copiare tutti gli elementi dalla coda 1 alla coda2. -per POP basta dequeue l'elemento dalla coda da te inserito l'ultimo elemento.

Così,

public void push(int data){
if (queue1.isEmpty()){
    queue1.enqueue(data);
}  else {
queue2.enqueue(data);
while(!queue1.isEmpty())
Queue2.enqueue(queue1.dequeue());
//EXCHANGE THE NAMES OF QUEUE 1 and QUEUE2

}}

public int pop(){
int popItem=queue2.dequeue();
return popItem;
}'

C'è un problema, non riesco a capire, come rinominare le code ???


0
#include <bits/stdc++.h>
using namespace std;
queue<int>Q;
stack<int>Stk;
void PRINT(stack<int>ss , queue<int>qq) {
    while( ss.size() ) {
        cout << ss.top() << " " ;
        ss.pop();
    }
    puts("");
    while( qq.size() ) {
        cout << qq.front() << " " ;
        qq.pop();
    }
    puts("\n----------------------------------");
}
void POP() {
    queue<int>Tmp ;
    while( Q.size() > 1 ) {
        Tmp.push( Q.front()  );
        Q.pop();
    }
    cout << Q.front() << " " << Stk.top() << endl;
    Q.pop() , Stk.pop() ;
    Q = Tmp ;
}
void PUSH(int x ) {
    Q.push(x);
    Stk.push(x);
}
int main() {
    while( true ) {
        string typ ;
        cin >> typ ;
        if( typ == "push" ) {
            int x ;
            cin >> x;
            PUSH(x);
        } else POP();
        PRINT(Stk,Q);
    }
}

1
Per favore, alcune parole, spiegando di cosa tratta questo codice e come questa cosa è in grado di aiutare l'OP a risolvere il suo problema, sarà molto apprezzata, insieme all'esempio di codice :-)
nIcE cOw

0

Codice Python utilizzando solo una coda

 class Queue(object):
    def __init__(self):
        self.items=[]
    def enqueue(self,item):
        self.items.insert(0,item)
    def dequeue(self):
        if(not self.isEmpty()):
            return  self.items.pop()
    def isEmpty(self):
        return  self.items==[]
    def size(self):
        return len(self.items)



class stack(object):
        def __init__(self):
            self.q1= Queue()


        def push(self, item):
            self.q1.enqueue(item) 


        def pop(self):
            c=self.q1.size()
            while(c>1):
                self.q1.enqueue(self.q1.dequeue())
                c-=1
            return self.q1.dequeue()



        def size(self):
            return self.q1.size() 


        def isempty(self):
            if self.size > 0:
               return True
            else:
               return False

1
Cerca di evitare di scaricare un codice come risposta e di spiegare cosa fa e perché. Il tuo codice potrebbe non essere ovvio per le persone che non hanno l'esperienza di programmazione pertinente.
Frits

0

ecco il codice di lavoro completo in c #:

È stato implementato con la coda singola,

spingere:

1. add new element.
2. Remove elements from Queue (totalsize-1) times and add back to the Queue

pop:

normal remove





 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace StackImplimentationUsingQueue
    {
        class Program
        {
            public class Node
            {
                public int data;
                public Node link;
            }
            public class Queue
            {
                public Node rear;
                public Node front;
                public int size = 0;
                public void EnQueue(int data)
                {
                    Node n = new Node();
                    n.data = data;
                    n.link = null;
                    if (rear == null)
                        front = rear = n;
                    else
                    {
                        rear.link = n;
                        rear = n;
                    }
                    size++;
                    Display();
                }
                public Node DeQueue()
                {
                    Node temp = new Node();
                    if (front == null)
                        Console.WriteLine("Empty");
                    else
                    {
                        temp = front;
                        front = front.link;
                        size--;
                    }
                    Display();
                    return temp;
                }
                public void Display()
                {
                    if (size == 0)
                        Console.WriteLine("Empty");
                    else
                    {
                        Console.Clear();
                        Node n = front;
                        while (n != null)
                        {
                            Console.WriteLine(n.data);
                            n = n.link;
                        }
                    }
                }
            }
            public class Stack
            {
                public Queue q;
                public int size = 0;
                public Node top;
                public Stack()
                {
                    q = new Queue();
                }
                public void Push(int data)
                {
                    Node n = new Node();
                    n.data = data;
                    q.EnQueue(data);
                    size++;
                    int counter = size;
                    while (counter > 1)
                    {
                        q.EnQueue(q.DeQueue().data);
                        counter--;
                    }
                }
                public void Pop()
                {
                    q.DeQueue();
                    size--;
                }
            }
            static void Main(string[] args)
            {
                Stack s= new Stack();
                for (int i = 1; i <= 3; i++)
                    s.Push(i);
                for (int i = 1; i < 3; i++)
                    s.Pop();
                Console.ReadKey();
            }
        }
    }

Vuoi commentare il tempo (atteso / ammortizzato) richiesto dalla tua implementazione in funzione degli elementi attualmente conservati / somma di push e pop?
Greybeard,

0

Ecco una soluzione molto semplice che utilizza una coda e offre funzionalità come Stack.

public class CustomStack<T>
{
    Queue<T> que = new Queue<T>();

    public void push(T t) // STACK = LIFO / QUEUE = FIFO
    {

        if( que.Count == 0)
        {
            que.Enqueue(t);
        }
        else
        {
            que.Enqueue(t);
            for (int i = 0; i < que.Count-1; i++)
            {
                var data = que.Dequeue();

                que.Enqueue(data);
            }
        }

    }

    public void pop()
    {

        Console.WriteLine("\nStack Implementation:");
        foreach (var item in que)
        {
            Console.Write("\n" + item.ToString() + "\t");
        }

        var data = que.Dequeue();
        Console.Write("\n Dequeing :" + data);
    }

    public void top()
    {

        Console.Write("\n Top :" + que.Peek());
    }


}

Quindi nella classe sopra denominata "CustomStack" quello che sto facendo è solo controllare la coda per vuoto, se vuoto quindi inserirne uno e da allora in poi inserire gli inserti e quindi rimuovere l'inserto. Secondo questa logica, la prima verrà per ultima. Esempio: nella coda ho inserito 1 e ora provo a inserire 2. La seconda volta rimuovi 1 e inserisci nuovamente in modo che diventi in ordine inverso.

Grazie.


0

Di seguito è una soluzione Java molto semplice che supporta l'operazione push efficiente.

Algoritmo -

  1. Dichiarare due code q1 e q2.

  2. Operazione push - Accoda l'elemento nella coda q1.

  3. Operazione pop: assicurarsi che la coda q2 non sia vuota. Se è vuoto, quindi dequeue tutti gli elementi da q1 tranne l'ultimo elemento e lo accoda a q2 uno per uno. Dequeue l'ultimo elemento da q1 e memorizzarlo come elemento saltato. Scambia le code q1 e q2. Restituisce l'elemento spuntato memorizzato.

  4. Operazione di sbirciatina: assicurarsi che la coda q2 non sia vuota. Se è vuoto, quindi dequeue tutti gli elementi da q1 tranne l'ultimo elemento e lo accoda a q2 uno per uno. Dequeue l'ultimo elemento da q1 e memorizzarlo come elemento sbirciato. Riattaccalo alla coda q2 e scambia le code q1 e q2. Restituisce l'elemento sbirciato memorizzato.

Di seguito è riportato il codice per l'algoritmo sopra -

class MyStack {

    java.util.Queue<Integer> q1;
    java.util.Queue<Integer> q2;
    int SIZE = 0;

    /** Initialize your data structure here. */
    public MyStack() {
        q1 = new LinkedList<Integer>();
        q2 = new LinkedList<Integer>();

    }

    /** Push element x onto stack. */
    public void push(int x) {
        q1.add(x);
        SIZE ++;

    }

    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        ensureQ2IsNotEmpty();
        int poppedEle = q1.remove();
        SIZE--;
        swapQueues();
        return poppedEle;
    }

    /** Get the top element. */
    public int top() {
        ensureQ2IsNotEmpty();
        int peekedEle = q1.remove();
        q2.add(peekedEle);
        swapQueues();
        return peekedEle;
    }

    /** Returns whether the stack is empty. */
    public boolean empty() {
        return q1.isEmpty() && q2.isEmpty();

    }

    /** move all elements from q1 to q2 except last element */
    public void ensureQ2IsNotEmpty() {
        for(int i=0; i<SIZE-1; i++) {
            q2.add(q1.remove());
        }
    }

    /** Swap queues q1 and q2 */
    public void swapQueues() {
        Queue<Integer> temp = q1;
        q1 = q2;
        q2 = temp;
    }
}

-1

Ecco la mia soluzione ..

Concept_Behind :: push(struct Stack* S,int data):: Questa funzione accoda il primo elemento in Q1 e riposa in Q2 pop(struct Stack* S):: se Q2 non è vuoto trasferisce tutti gli elementi in Q1 e restituisce l'ultimo elemento in Q2 altrimenti (il che significa che Q2 è vuoto) trasferisce tutti gli elementi in Q2 e restituisce l'ultimo elem in Q1

Efficiency_Behind :: push(struct Stack*S,int data):: O (1) // poiché single enqueue per data pop(struct Stack* S):: O (n) // poiché trasferisce i peggiori dati n-1 per pop.

#include<stdio.h>
#include<stdlib.h>
struct Queue{
    int front;
    int rear;
    int *arr;
    int size;
    };
struct Stack {
    struct Queue *Q1;
    struct Queue *Q2;
    };
struct Queue* Qconstructor(int capacity)
{
    struct Queue *Q=malloc(sizeof(struct Queue));
    Q->front=Q->rear=-1;
    Q->size=capacity;
    Q->arr=malloc(Q->size*sizeof(int));
    return Q;
    }
int isEmptyQueue(struct Queue *Q)
{
    return (Q->front==-1);
    }
int isFullQueue(struct Queue *Q)
{
    return ((Q->rear+1) % Q->size ==Q->front);
    }
void enqueue(struct Queue *Q,int data)
{
    if(isFullQueue(Q))
        {
            printf("Queue overflow\n");
            return;}
    Q->rear=Q->rear+1 % Q->size;
    Q->arr[Q->rear]=data;
    if(Q->front==-1)
        Q->front=Q->rear;
        }
int dequeue(struct Queue *Q)
{
    if(isEmptyQueue(Q)){
        printf("Queue underflow\n");
        return;
        }
    int data=Q->arr[Q->front];
    if(Q->front==Q->rear)
        Q->front=-1;
    else
    Q->front=Q->front+1 % Q->size;
    return data;
    }
///////////////////////*************main algo****************////////////////////////
struct Stack* Sconstructor(int capacity)
{
    struct Stack *S=malloc(sizeof(struct Stack));
    S->Q1=Qconstructor(capacity);
    S->Q2=Qconstructor(capacity);
    return S;
}
void push(struct Stack *S,int data)
{
    if(isEmptyQueue(S->Q1))
        enqueue(S->Q1,data);
    else
        enqueue(S->Q2,data);
    }
int pop(struct Stack *S)
{
    int i,tmp;
    if(!isEmptyQueue(S->Q2)){
        for(i=S->Q2->front;i<=S->Q2->rear;i++){
            tmp=dequeue(S->Q2);
            if(isEmptyQueue(S->Q2))
                return tmp;
            else
                enqueue(S->Q1,tmp);
                }
            }
    else{
        for(i=S->Q1->front;i<=S->Q1->rear;i++){
            tmp=dequeue(S->Q1);
            if(isEmptyQueue(S->Q1))
                return tmp;
            else
                enqueue(S->Q2,tmp);
                }
            }
        }
////////////////*************end of main algo my algo************
///////////////*************push() O(1);;;;pop() O(n);;;;*******/////
main()
{
    int size;
    printf("Enter the number of elements in the Stack(made of 2 queue's)::\n");
    scanf("%d",&size);
    struct Stack *S=Sconstructor(size);
    push(S,1);
    push(S,2);
    push(S,3);
    push(S,4);
    printf("%d\n",pop(S));
    push(S,5);
    printf("%d\n",pop(S));
    printf("%d\n",pop(S));
    printf("%d\n",pop(S));
    printf("%d\n",pop(S));
    }

-1
import java.util.LinkedList;
import java.util.Queue;


public class StackQueue {

    static Queue<Integer> Q1 = new LinkedList<Integer>();
    static Queue<Integer> Q2 = new LinkedList<Integer>();
    public static void main(String args[]) {



        push(24);
        push(34);
        push(4);
        push(10);
        push(1);
        push(43);
        push(21);
        System.out.println("Popped element is  "+pop());
        System.out.println("Popped element is  "+pop());
        System.out.println("Popped element is  "+pop());


    }

    public static void push(int data) {

        Q1.add(data);

    }

    public static int pop() {

        if(Q1.isEmpty()) {
        System.out.println("Cannot pop elements ,  Stack is Empty !!"); 
        return -1;
        }
        else
        {
        while(Q1.size() > 1) {
            Q2.add(Q1.remove());
        }
        int element = Q1.remove();
        Queue<Integer> temp = new LinkedList<Integer>();
        temp = Q1;
        Q1 = Q2;
        Q2 = temp;
        return element;
        }
    }
}

Un elenco collegato Java funziona come un deque bene. Questa risposta non ha senso.
dfeuer,

-1
#include "stdio.h"
#include "stdlib.h"

typedef struct {
    int *q;
    int size;
    int front;
    int rear;
} Queue;
typedef struct {
    Queue *q1;
    Queue *q2;
} Stack;

int queueIsEmpty(Queue *q) {
    if (q->front == -1 && q->rear == -1) {
        printf("\nQUEUE is EMPTY\n");
        return 1;
    }
    return 0;
}
int queueIsFull(Queue *q) {
    if (q->rear == q->size-1) {
        return 1;
    }
    return 0;
}
int queueTop(Queue *q) {
    if (queueIsEmpty(q)) {
        return -1;
    }
    return q->q[q->front];
}
int queuePop(Queue *q) {
    if (queueIsEmpty(q)) {
        return -1;
    }
    int item = q->q[q->front];
    if (q->front == q->rear) {
        q->front = q->rear = -1;
    }
    else {
        q->front++;
    }
    return item;
}
void queuePush(Queue *q, int val) {
    if (queueIsFull(q)) {
        printf("\nQUEUE is FULL\n");
        return;
    }
    if (queueIsEmpty(q)) {
        q->front++;
        q->rear++;
    } else {
        q->rear++;
    }
    q->q[q->rear] = val;
}
Queue *queueCreate(int maxSize) {
    Queue *q = (Queue*)malloc(sizeof(Queue));
    q->front = q->rear = -1;
    q->size = maxSize;
    q->q = (int*)malloc(sizeof(int)*maxSize);
    return q;
}
/* Create a stack */
void stackCreate(Stack *stack, int maxSize) {
    Stack **s = (Stack**) stack;
    *s = (Stack*)malloc(sizeof(Stack));
    (*s)->q1 = queueCreate(maxSize);
    (*s)->q2 = queueCreate(maxSize);
}

/* Push element x onto stack */
void stackPush(Stack *stack, int element) {
    Stack **s = (Stack**) stack;
    queuePush((*s)->q2, element);
    while (!queueIsEmpty((*s)->q1)) {
        int item = queuePop((*s)->q1);
        queuePush((*s)->q2, item);
    }
    Queue *tmp = (*s)->q1;
    (*s)->q1 = (*s)->q2;
    (*s)->q2 = tmp;
}

/* Removes the element on top of the stack */
void stackPop(Stack *stack) {
    Stack **s = (Stack**) stack;
    queuePop((*s)->q1);
}

/* Get the top element */
int stackTop(Stack *stack) {
    Stack **s = (Stack**) stack;
    if (!queueIsEmpty((*s)->q1)) {
      return queueTop((*s)->q1);
    }
    return -1;
}

/* Return whether the stack is empty */
bool stackEmpty(Stack *stack) {
    Stack **s = (Stack**) stack;
    if (queueIsEmpty((*s)->q1)) {
        return true;
    }
    return false;
}

/* Destroy the stack */
void stackDestroy(Stack *stack) {
    Stack **s = (Stack**) stack;
    free((*s)->q1);
    free((*s)->q2);
    free((*s));
}

int main()
{
  Stack *s = NULL;
  stackCreate((Stack*)&s, 10);
  stackPush((Stack*)&s, 44);
  //stackPop((Stack*)&s);
  printf("\n%d", stackTop((Stack*)&s));
  stackDestroy((Stack*)&s);
  return 0;
}

Un muro di codice senza commenti o spiegazioni è una risposta scadente.
Richard,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.