Implementieren Sie den Stapel mithilfe von zwei Warteschlangen


142

Eine ähnliche Frage wurde früher gefragt , dort , aber die Frage hier ist das Gegenteil davon, unter Verwendung von zwei Warteschlangen als Stapel. Die Frage...

Gegeben seien zwei Warteschlangen mit ihren Standard - Operationen ( enqueue, dequeue, isempty, size), implementieren einen Stapel mit seinen Standard - Operationen ( pop, push, isempty, size).

Es sollte zwei Versionen der Lösung geben.

  • Version A : Der Stapel sollte beim Schieben eines Elements effizient sein. und
  • Version B : Der Stapel sollte beim Poppen eines Elements effizient sein.

Ich interessiere mich mehr für den Algorithmus als für bestimmte Sprachimplementierungen. Ich begrüße jedoch Lösungen, die in mir vertrauten Sprachen ausgedrückt werden (,,,,,).


6
Sicher ist es das! CLRS - 10.1-6 ( tinyurl.com/clrs-ex-10-1-6 )
Rampion

1
One Stack, Two Queues bietet eine elegante Lösung, bei der Popin $ O (1) $ und Pushin $ O (\ sqrt {n}) $ amortisierter Zeit gearbeitet wird.
Hengxin

1
@rampion Jetzt ist es CLRS - 10.1-7. :)
nsane

Verwandter Beitrag. Dies ist ein weiteres interessantes Problem Stack zu implementieren mit nur einer Warteschlange hier .
RBT

Antworten:


194

Version A (effizienter Push):

  • drücken:
    • Warteschlange in Warteschlange1
  • Pop:
    • Während die Größe von Warteschlange1 größer als 1 ist, werden Elemente aus der Warteschlange1 in die Warteschlange2 geleitet
    • Entfernen Sie das letzte Element von Warteschlange1 und geben Sie es zurück. Wechseln Sie dann die Namen von Warteschlange1 und Warteschlange2

Version B (effizienter Pop):

  • drücken:
    • Warteschlange in Warteschlange2
    • Alle Elemente von Warteschlange1 in Warteschlange2 in die Warteschlange stellen und dann die Namen von Warteschlange1 und Warteschlange2 wechseln
  • Pop:
    • deqeue from queue1

4
Version B scheint ein Problem zu haben: Meinen Sie damit, dass Sie alle Elemente von Warteschlange2 bis auf das letzte Element in Warteschlange1 einreihen (und dann die Namen von q1 und q2 wechseln)?
Icerman

Der Kommentar von Icerman macht für mich Sinn. Die Version B der Antwort muss bearbeitet werden. Ich habe keine Bearbeitungsberechtigungen. Könnte jemand bitte diese Antwort bearbeiten?
Eeerahul

2
@eeerahul: Ich habe es noch einmal überprüft und die Antwort ist richtig. Zu der Zeit Icerman alle Artikel von Queue2 in queue1 einzureihen scheint zu wollen, besteht Queue2 nur an der neuen Sache, so der Kommentar ist nicht sinnvoll.
Svante

Ist Version A richtig? Drücken Sie 1, drücken Sie 2, drücken Sie 3, drücken Sie 4. Pop 4. Drücken Sie 5, drücken Sie 6, drücken Sie 7, drücken Sie 8. Pop 8. Pop 7. Scheint, als würde dieser Algorithmus 3 statt 7 knallen. Ihr Algorithmus scheint richtig zu sein Erster Blick, weil wir möglicherweise folgendes argumentieren können: Grundsätzlich werden Sie immer das letzte in die Warteschlange gestellte Element in Warteschlange 1 platzieren. Dies ist jedoch nur dann das zuletzt gepostete Element, wenn Sie zuvor in die Warteschlange gestellt haben. Wenn Sie mehrmals hintereinander aufgetaucht sind, muss dies nicht zutreffen.
user127.0.0.1

1
@ user127.0.0.1: Es scheint, dass Sie vergessen haben, die Warteschlangen am Ende jedes Pops zu wechseln. Es gibt eine Invariante, dass sich nach jedem Push und jedem Pop alle Elemente in Warteschlange1 befinden, während Warteschlange2 leer ist.
Svante

68

Der einfachste (und vielleicht einzige) Weg, dies zu tun, besteht darin, neue Elemente in die leere Warteschlange zu verschieben, die anderen in die Warteschlange zu stellen und in die zuvor leere Warteschlange zu stellen. Auf diese Weise steht immer das Neueste an der Spitze der Warteschlange. Dies wäre Version B, für Version A kehren Sie den Vorgang einfach um, indem Sie die Elemente mit Ausnahme der letzten in die zweite Warteschlange einreihen.

Schritt 0:

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

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

Schritt 1:

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

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

Schritt 2:

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

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

Schritt 3:

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

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

1
Die Logik dafür macht keinen Sinn. Gehen Sie von Schritt 2 zu Schritt 3 über. Wenn ich 3 "drücke", wie kann ich Elemente in Warteschlange B so aus der Warteschlange entfernen, dass ich 3 2 1 in Warteschlange A erhalte? Wenn ich B in die Warteschlange A stelle, kann ich nur Elemente in der Reihenfolge 2, 1 erhalten. Wenn ich dann 3 addiere, erhalte ich die Reihenfolge 3, 1, 2. Wenn ich zuerst meinen Push und dann die Warteschlange / Warteschlange stelle, erhalte ich 1, 2, 3.
Tsurantino

Warum nicht die Deque-Operation teurer machen als die Enqueue-Operation?
Divij Sehgal

49

Wir können dies mit einer Warteschlange tun:

drücken:

  1. neues Element in die Warteschlange stellen.
  2. Wenn ndie Anzahl der Elemente in der Warteschlange ist, entfernen Sie die Elementzeiten und fügen Sie sie ein n-1.

Pop:

  1. aus der Warteschlange

.

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
+----+----+----+----+----+----+

Beispielimplementierung:

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());
    }
}

Könnte jemand das Login hinter der Push-Methode im obigen Code erklären? Soweit ich verstanden habe, entfernt die erste for-Schleife alle Elemente in q2, bis in q1 noch ein Element übrig ist. Bitte korrigieren Sie mich, wenn ich falsch liege.
John

4

Können wir nur eine Warteschlange verwenden, um einen Stapel zu implementieren? Ich kann zwei Warteschlangen verwenden, aber es wäre effizienter, eine einzelne Warteschlange in Betracht zu ziehen. Hier ist der Code:

    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();

    }

Ich denke in der Pop-Methode sollte die for-Schleifenbedingung i <queLower.Count - 2 sein, da Sie die Variable i mit 0 initialisieren.
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

Hier ist meine Antwort - wo der "Pop" ineffizient ist. Es scheint, dass alle Algorithmen, die sofort in den Sinn kommen, eine N-Komplexität haben, wobei N die Größe der Liste ist: ob Sie sich für die Arbeit am 'Pop' oder für die Arbeit am 'Push' entscheiden.

Der Algorithmus, bei dem Listen zurück und viertens gehandelt werden, ist möglicherweise besser, da keine Größenberechnung erforderlich ist, obwohl Sie immer noch eine Schleife erstellen und mit leer vergleichen müssen.

Sie können beweisen, dass dieser Algorithmus nicht schneller als N geschrieben werden kann, indem Sie feststellen, dass die Informationen über das letzte Element in einer Warteschlange nur verfügbar sind, wenn Sie die Größe der Warteschlange kennen, und dass Sie Daten zerstören müssen, um zu diesem Element zu gelangen, daher die zweite Warteschlange .

Die einzige Möglichkeit, dies zu beschleunigen, besteht darin, überhaupt keine Warteschlangen zu verwenden.

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

Hier ist meine Lösung, die im Durchschnitt für O (1) funktioniert. Es gibt zwei Warteschlangen: inund out. Siehe Pseudocode unten:

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
Dort verwenden Sie 2 Warteschlangen und 1 Stapel, um 1 Stapel zu simulieren!
BeniBela

Meinen Sie implizieren Rekursionsstapel?
Vladimir Kostyukov

1

Wie bereits erwähnt, würde nicht eine einzige Warteschlange den Trick machen? Es ist wahrscheinlich weniger praktisch, aber etwas schlauer.

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

pop(x):
dequeue()

1

Hier ist ein einfacher Pseudocode: Push ist O (n), Pop / Peek ist 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

Es seien S1 und S2 die beiden Stapel, die bei der Implementierung von Warteschlangen verwendet werden sollen.

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

Wir stellen sicher, dass immer eine Warteschlange leer ist.

Push-Vorgang: Unabhängig davon, welche Warteschlange nicht leer ist, fügen Sie das Element ein.

  • Überprüfen Sie, ob die Warteschlange Q1 leer ist oder nicht. Wenn Q1 leer ist, wird das darin enthaltene Element in die Warteschlange gestellt.
  • Andernfalls setzen Sie das Element in Q1 ein.

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

Zeitkomplexität: O (1)

Pop-Operation: Übertragen Sie n-1 Elemente in eine andere Warteschlange und löschen Sie sie zuletzt aus der Warteschlange, um die Pop-Operation auszuführen.

  • Wenn die Warteschlange Q1 nicht leer ist, übertragen Sie n-1 Elemente von Q1 nach Q2. DeQueue das letzte Element von Q1 und gibt es zurück.
  • Wenn die Warteschlange Q2 nicht leer ist, übertragen Sie n-1 Elemente von Q2 nach Q1. DeQueue das letzte Element von Q2 und gibt es zurück.

`

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);
} }

Zeitkomplexität: Laufzeit von Pop Operation ist O (n), da bei jedem Aufruf von Pop alle Elemente von einer Warteschlange in eine andere übertragen werden.


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

Hier ist noch eine Lösung:

für PUSH: - Fügen Sie das erste Element in Warteschlange 1 hinzu. - Wenn Sie ein zweites Element usw. hinzufügen, stellen Sie das Element zuerst in Warteschlange 2 in die Warteschlange und kopieren Sie dann das gesamte Element von Warteschlange 1 in Warteschlange 2. -für POP wird das Element einfach aus der Warteschlange entfernt, nachdem Sie das letzte Element eingefügt haben.

So,

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;
}'

Es gibt ein Problem, ich kann nicht herausfinden, wie man die Warteschlangen umbenennt ???


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
Bitte einige Worte, die erklären, worum es in diesem Code geht und wie dieses Ding dem OP bei der Lösung seines Problems helfen kann, werden zusammen mit dem Codebeispiel sehr geschätzt :-)
nIcE cOw

0

Python-Code mit nur einer Warteschlange

 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
Bitte versuchen Sie zu vermeiden, nur einen Code als Antwort auszugeben, und versuchen Sie zu erklären, was er tut und warum. Ihr Code ist möglicherweise nicht offensichtlich für Personen, die nicht über die entsprechende Codierungserfahrung verfügen.
Frits

0

Hier ist der vollständige Arbeitscode in c #:

Es wurde mit Single Queue implementiert,

drücken:

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();
            }
        }
    }

Möchten Sie die (erwartete / amortisierte) Zeit kommentieren, die Ihre Implementierung in Abhängigkeit von den aktuell gespeicherten Elementen / der Summe der Pushs & Pops benötigt?
Graubart

0

Hier ist eine sehr einfache Lösung, die eine Warteschlange verwendet und Funktionen wie Stack bietet.

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());
    }


}

In der obigen Klasse mit dem Namen "CustomStack" überprüfe ich nur die Warteschlange auf leer. Wenn sie leer ist, fügen Sie eine ein und von da an wird sie eingefügt und dann eingefügt. Nach dieser Logik wird zuerst zuerst kommen. Beispiel: In die Warteschlange habe ich 1 eingefügt und versuche nun, 2 einzufügen. Entfernen Sie zum zweiten Mal 1 und fügen Sie es erneut ein, damit es in umgekehrter Reihenfolge angezeigt wird.

Danke dir.


0

Im Folgenden finden Sie eine sehr einfache Java-Lösung, die den Push-Vorgang effizient unterstützt.

Algorithmus -

  1. Deklarieren Sie zwei Warteschlangen q1 und q2.

  2. Push-Operation - Element in Warteschlange q1 einreihen.

  3. Pop-Vorgang - Stellen Sie sicher, dass die Warteschlange q2 nicht leer ist. Wenn es leer ist, entfernen Sie alle Elemente aus q1 mit Ausnahme des letzten Elements und stellen Sie es nacheinander in q2 ein. Dequeue das letzte Element von q1 und speichern Sie es als das geplatzte Element. Tauschen Sie die Warteschlangen q1 und q2 aus. Geben Sie das gespeicherte Element zurück.

  4. Peek-Operation - Stellen Sie sicher, dass die Warteschlange q2 nicht leer ist. Wenn es leer ist, entfernen Sie alle Elemente aus q1 mit Ausnahme des letzten Elements und stellen Sie es nacheinander in q2 ein. Entfernen Sie das letzte Element aus q1 und speichern Sie es als gespähtes Element. Stellen Sie es wieder in die Warteschlange q2 und tauschen Sie die Warteschlangen q1 und q2 aus. Gibt das gespeicherte Peeked-Element zurück.

Unten ist der Code für den obigen Algorithmus -

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

Hier ist meine Lösung ..

Concept_Behind :: push(struct Stack* S,int data):: Diese Funktion stellt das erste Element in Q1 in die Warteschlange und ruht in Q2 pop(struct Stack* S) :: Wenn Q2 nicht leer ist, werden alle Elemente in Q1 übertragen und das letzte Element in Q2 zurückgegeben. Andernfalls (was bedeutet, dass Q2 leer ist) werden alle Elemente in Q2 und übertragen gibt das letzte Element in Q1 zurück

Efficiency_Behind :: push(struct Stack*S,int data):: O (1) // da einzelne Enqueue pro Daten pop(struct Stack* S):: O (n) // da die schlechtesten n-1 Daten pro Pop übertragen werden.

#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;
        }
    }
}

Eine Java-verknüpfte Liste fungiert als Deque. Diese Antwort macht keinen Sinn.
Feuer

-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;
}

Eine Codewand ohne Kommentare oder Erklärungen ist eine schlechte Antwort.
Richard
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.