İki Kuyruk Kullanarak Yığını Uygulama


143

Benzer bir soru daha önce orada sorulmuştu , ancak buradaki soru bunun tersi, yığın olarak iki kuyruk kullanıyor. Soru...

Standart işlemleri ile iki sıraları göz önüne alındığında ( enqueue, dequeue, isempty, size), standart işlemler ile yığın aleti ( pop, push, isempty, size).

Çözümün iki sürümü olmalıdır .

  • Sürüm A : Bir öğeyi iterken yığın verimli olmalıdır; ve
  • Sürüm B : Bir öğeyi patlatırken yığın verimli olmalıdır.

Algoritma herhangi bir dil uygulamasından daha çok ilgi duyuyorum. Ancak, bildiğim dillerde ifade edilen çözümleri memnuniyetle karşılıyoruz (,,,,,).


6
Tabiki öyle! CLRS - 10.1-6 ( tinyurl.com/clrs-ex-10-1-6 )
azgın

1
Bir Yığın, İki Kuyruk , Pop$ O (1) $ ve Push$ O (\ sqrt {n}) $ amortisman süresinde çalışan zarif bir çözüm sunar .
hengxin

1
@rampion Şimdi CLRS - 10.1-7. :)
nsane

İlgili yazı. Bu, burada yalnızca bir kuyruk kullanarak yığını uygulamak için ilginç bir sorundur .
RBT

Yanıtlar:


194

Versiyon A (verimli itme):

  • it:
    • kuyrukta enque1
  • pop:
    • sıra1'in boyutu 1'den büyük olsa da, sıradan alınan öğeleri sıra1'den sıra2'ye geçir
    • kuyruk1'in son öğesini ayıklayın ve döndürün, ardından kuyruk1 ve kuyruk2'nin adlarını değiştirin

Versiyon B (verimli pop):

  • it:
    • kuyruk 2'de enqueue
    • kuyruk2'deki tüm kuyruk1 öğelerini enqueue edin, sonra kuyruk1 ve kuyruk2'nin adlarını değiştirin
  • pop:
    • kuyruktan deqeue1

4
Sürüm B sorun yaşıyor gibi görünüyor: son öğe dışında sıra 2'nin sıra öğelerini sıra1'e sırayla mı kastediyorsunuz (q1 ve q2'nin adlarını değiştirin)?
Icerman

Icerman'ın yorumu bana mantıklı geliyor. Cevabın B Versiyonu bir düzenleme gerektiriyor. Düzenleme iznim yok. Birisi bu cevabı düzenleyebilir mi?
eeerahul

2
@eeerahul: Tekrar kontrol ettim ve cevap doğru. Icerman, sıra2'deki tüm öğeleri sıra1'e ayırmak istiyor gibi görünüyorsa, sıra2 yalnızca yeni öğeden oluşur, bu nedenle yorum mantıklı değildir .
Svante

Sürüm A doğru mu? itme 1, itme 2, itme 3, itme 4. pop 4. itme 5, itme 6, itme 7, itme 8 pop 8. pop 7. Görünüşe göre algoritma 7 yerine 3 çıkacak gibi görünüyor. Algoritmanız doğru görünüyor ilk bakışta çünkü muhtemelen şu şekilde düşünebiliriz: temel olarak her zaman Sıra 1'deki son enqueued elemanını patlatacaksınız. Ama bu sadece daha önce sıraya koyduysanız itilen son eleman. Art arda birden çok kez atladıysanız, bunun doğru olması gerekmez.
user127.0.0.1

1
@ user127.0.0.1: Her popun sonunda sıraları değiştirmeyi unuttuğunuz anlaşılıyor. Her itme ve her pop'dan sonra, sıra2'nin boşken tüm öğelerin kuyruk1'de olduğu bir değişmez vardır.
Svante

68

Bunu yapmanın en kolay (ve belki de sadece) yolu, yeni öğeleri boş kuyruğa sokmak ve sonra diğerini ayıklamak ve önceki boş kuyruğa sokmaktır. Bu şekilde sonuncusu daima kuyruğun önünde olur. Bu B sürümü olacaktır, A sürümü için, sadece sonuncusu hariç öğeleri ikinci kuyruğa atayarak işlemi tersine çevirirsiniz.

Adım 0:

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

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

Aşama 1:

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

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

Adım 2:

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

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

Aşama 3:

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

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

1
Bunun mantığı bir anlam ifade etmiyor. Adım 2'den Adım 3'e geçin. 3'e "bastığımda", Sıra B'deki öğeleri, Sıra A'da 3 2 1 elde edecek şekilde nasıl dequeue edebilirim? A'yı enqueue yapmak için B'yi dequeue edersem, yalnızca 2., 1. sırayla eleman alabilirim. Sonra 3 eklersem, 3, 1, 2 sırasını alırım. 1, 2, 3.
tsurantino

neden deque operasyonunu enqueue operasyonunu pahalı yapmaktan daha pahalı hale getirmiyorsunuz?
Divij Sehgal

49

Bunu tek bir kuyrukla yapabiliriz:

it:

  1. yeni öğeyi enqueue.
  2. Eğer nkuyrukta eleman sayısıdır, çıkarıp eleman ekleme n-1süreleri.

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

Örnek uygulama:

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

Yukarıdaki kodda push yönteminin arkasındaki girişi açıklayan var mı? Anladığım kadarıyla, döngü için ilk, q1'de bir öğe kalana kadar tüm elemanları q2'ye çıkarmaktır. Yanlışım varsa lütfen düzelt.
John

4

Bir yığını uygulamak için yalnızca bir kuyruk kullanabilir miyiz? İki kuyruk kullanabilirim, ancak tek kuyruğu düşünmek daha verimli olurdu. İşte kod:

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

    }

Pop yönteminde sanırım, for döngüsü koşulu i <queLower.Count - 2 olmalıdır . Değişken i 0 ile başlatılırken
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

İşte cevabım - 'pop'un verimsiz olduğu yer. Hemen akla gelen tüm algoritmaların N karmaşıklığı var gibi görünüyor, burada N listenin boyutu: ister 'pop' üzerinde çalışmayı ya da 'push' üzerinde çalışmayı seçin

Listelerin geriye ve dördüncü olarak alınıp alındığı algoritma daha iyi olabilir, çünkü yine de döngü ve boş ile karşılaştırmanız gerekir.

bir kuyruktaki son öğe hakkındaki bilgilerin yalnızca kuyruğun boyutunu bilerek kullanılabilir olduğunu ve bu öğeye ulaşmak için verileri yok etmeniz gerektiğini, dolayısıyla 2. kuyruğu bu algoritmanın N'den daha hızlı yazılamayacağını kanıtlayabilirsiniz. .

Bunu daha hızlı yapmanın tek yolu, kuyrukları ilk etapta kullanmamaktır.

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

İşte ortalama durumda O (1) için çalışan çözümüm. İki kuyruk vardır: inve out. Aşağıdaki sahte kod bakınız:

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
Orada 1 yığını simüle etmek için 2 kuyruk ve 1 yığın kullanıyorsunuz!
BeniBela

Yani özyinelemeli yığın yığını mı demek istediniz?
Vladimir Kostyukov

1

Belirtildiği gibi, tek bir kuyruk hile yapmaz mı? Muhtemelen daha az pratik ama biraz daha ince.

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

pop(x):
dequeue()

1

İşte bazı basit sahte kod, itme 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

S1 ve S2, kuyrukların uygulanmasında kullanılacak iki Yığın olsun.

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

Bir kuyruğun her zaman boş olduğundan emin oluruz.

İtme işlemi: Hangi sıra boş değilse, öğeyi içine yerleştirin.

  • Q1 kuyruğunun boş olup olmadığını kontrol edin. Q1 boşsa içindeki öğeyi sıkın.
  • Aksi takdirde Elemanı Q1'e sıralayın.

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

Zaman Karmaşıklığı: O (1)

Pop Çalışması: n-1 öğelerini diğer kuyruğa aktarın ve pop işlemini gerçekleştirmek için kuyruktan sonuncuyu silin.

  • Q1 kuyruğu boş değilse, n-1 öğelerini Q1'den Q2'ye aktarın ve sonra Q1'in son öğesini DeQueue yapın ve geri gönderin.
  • Q2 kuyruğu boş değilse, n-1 öğelerini Q2'den Q1'e aktarın ve sonra Q2'nin son öğesini DeQueue yapın ve geri gönderin.

'

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

Zaman Karmaşıklığı: Pop'un Çalışma Süresi Pop'un her çağrılışında Operasyon O (n) olur, tüm öğeleri bir kuyruktan diğerine aktarıyoruz.


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

İşte bir çözüm daha:

PUSH için: -Sıra 1'deki ilk elemanı ekle. -İkinci eleman vb. eklerken, önce sıra 2'deki elemanı sıkın ve sonra sıra 1'den sıra2'ye tüm elemanı kopyalayın. -PO için sadece son öğeyi eklediğiniz kuyruktaki öğeyi ayıklayın.

Yani,

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

Bir sorun var, anlayamıyorum, nasıl sıraları yeniden adlandırmak ???


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
Lütfen bu kodun ne hakkında olduğunu ve bu şeyin OP'nin problemini çözmede nasıl yardımcı olabileceğini açıklayan bazı kelimeler, örnek kod ile birlikte çok takdir edilecektir :-)
nIcE cOw

0

Yalnızca Bir Kuyruk Kullanan Python Kodu

 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
Lütfen bir kodu yanıt olarak atmaktan kaçının ve ne yaptığını ve nedenini açıklamaya çalışın. Kodunuz, ilgili kodlama deneyimine sahip olmayan kişiler için açık olmayabilir.
Frits

0

İşte c # tam çalışma kodu:

Tek Sıra ile uygulandı,

it:

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

Şu anda tutulan öğelerin / itme ve popların toplamının bir fonksiyonu olarak uygulamanızın gerektirdiği (beklenen / itfa edilmiş) zaman hakkında yorum yapmak ister misiniz?
greybeard

0

İşte bir Kuyruk kullanan ve Stack gibi işlevsellik veren çok basit bir çözüm.

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


}

Yani "CustomStack" adlı yukarıdaki sınıfta yaptığım şey sadece boş için kuyruğu kontrol etmektir, eğer boşsa, sonra bir tane ekleyin ve oradan koğuşta insert ekleyin ve sonra insert'i kaldırın. Bu mantıkla ilk önce gelecek. Örnek: Kuyruğa 1 ekledim ve şimdi 2 eklemeye çalışıyorum. İkinci kez 1'i çıkarın ve ters sırada olacak şekilde takın.

Teşekkür ederim.


0

Aşağıda itme işlemini verimli destekleyen çok basit bir Java çözümü bulunmaktadır.

Algoritma -

  1. Q1 ve q2 olmak üzere iki Kuyruk bildirin.

  2. Push operasyonu - Q1 kuyruğundaki elemanı enqueue.

  3. Pop işlemi - q2 kuyruğunun boş olmadığından emin olun. Boşsa, son eleman hariç q1 öğesindeki tüm öğeleri ayıklayın ve tek tek q2 değerine kadar sıralayın. Son öğeyi q1'den ayırın ve açılan öğe olarak saklayın. Q1 ve q2 kuyruklarını değiştirin. Depolanan açılan öğeyi döndürür.

  4. Peek işlemi - q2 kuyruğunun boş olmadığından emin olun. Boşsa, son eleman hariç q1 öğesindeki tüm öğeleri ayıklayın ve tek tek q2 değerine kadar sıralayın. Q1'den son elemanı ayıkla ve gözetleme elemanı olarak sakla. Q2 kuyruğuna geri sıkın ve q1 ve q2 kuyruklarını değiştirin. Depolanan gözetlenen öğeyi döndürür.

Yukarıdaki algoritmanın kodu aşağıdadır -

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

İşte benim çözümüm ..

Concept_Behind :: push(struct Stack* S,int data):: Bu işlev birinci çeyrekte ilk öğeyi sırayla ve Q2'de dinlenmeyi sağlar pop(struct Stack* S):: Q2 boş değilse, tüm elemlerin Q1'e aktarır ve son elem'i Q2'ye geri gönderir (yani Q2 boş demektir) tüm elemlerin Q2'ye aktarır ve ilk çeyrekte son elemini döndürüyor

Efficiency_Behind :: push(struct Stack*S,int data):: O (1) // çünkü veri başına tek bir enqueue pop(struct Stack* S):: O (n) // çünkü pop başına en kötü n-1 verilerini aktarır.

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

Java bağlantılı bir liste deque deque olarak işlev görür. Bu cevap mantıklı değil.
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;
}

Yorum veya açıklama içermeyen bir kod duvarı zayıf bir cevaptır.
Richard
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.