두 개의 대기열을 사용하여 스택 구현


143

비슷한 질문은 이전 질문을 받았다 가 , 그러나 여기에서 문제는 스택으로 두 개의 큐를 사용하여, 그것의 반대입니다. 질문...

자신의 표준 운영과 두 개의 큐를 감안할 때 ( enqueue, dequeue, isempty, size), 표준 운영과 스택을 구현 ( pop, push, isempty, size).

솔루션 에는 두 가지 버전 이 있어야합니다 .

  • 버전 A : 아이템을 밀 때 스택이 효율적이어야합니다. 과
  • 버전 B : 아이템을 쓸 때 스택이 효율적이어야합니다.

특정 언어 구현보다 알고리즘에 관심이 있습니다. 그러나 친숙한 언어로 표현 된 솔루션을 환영합니다.,,,,,).


6
당연히 그렇지! CLRS - 10.1-6 ( tinyurl.com/clrs-ex-10-1-6 )
— rampion

1
One Stack, Two Queues 는 Pop$ O (1) $에서 Push작동하며 $ O (\ sqrt {n}) $에서 상각 된 시간에 작동 하는 우아한 솔루션을 제공 합니다 .
— hengxin

1
@rampion 이제 CLRS-10.1-7. :)
— nsane

관련 게시물. 이것은 사용하여 스택을 구현하는 또 다른 흥미로운 문제 하나 하나의 큐를 여기에 .
— RBT

답변:


194

버전 A (효율적인 푸시) :

  • 푸시:
    • queue1에 넣다
  • 팝:
    • queue1의 크기가 1보다 큰 동안 큐에서 대기 한 항목을 queue1에서 queue2로 파이프
    • queue1의 마지막 항목을 대기열에서 빼고 반환 한 다음 queue1과 queue2의 이름을 전환하십시오.

버전 B (효율적인 팝) :

  • 푸시:
    • queue2에 넣다
    • queue2의 모든 queue1 항목을 대기열에 넣은 다음 queue1 및 queue2의 이름을 전환하십시오.
  • 팝:
    • queue1에서 deqeue

4
버전 B에 문제가있는 것 같습니다 : 마지막 요소를 제외한 queue2의 모든 항목을 queue1에 대기열에 넣은 것을 의미합니까 (그런 다음 q1과 q2의 이름을 바꾸십시오)?
— Icerman

Icerman의 의견은 저에게 의미가 있습니다. 답변의 버전 B는 편집이 필요합니다. 편집 권한이 없습니다. 누군가이 답변을 편집 할 수 있습니까?
— eeerahul

2
@eeerahul : 다시 확인했는데 답이 맞습니다. Icerman이 queue2의 모든 항목을 queue1에 대기열에 넣고 싶어 할 때 queue2는 새 항목으로 만 구성되므로 주석이 의미 가 없습니다 .
— Svante

버전 A가 맞습니까? 1을 누르십시오. 2를 누르십시오. 3을 누르십시오. 4를 누르십시오. pop 4. 5를 누르십시오, 6을 누르십시오, 7, 7, 8을 누르십시오. pop 8. pop 7. 해당 알고리즘이 7 대신 3이 튀는 것처럼 보입니다. 우리는 아마도 다음과 같이 추론 할 수 있기 때문에 언뜻보기 : 기본적으로 항상 대기열 1에서 마지막으로 대기열에 넣은 요소를 팝 할 것입니다. 그러나 그것은 이전에 대기열에 놓인 경우에만 마지막으로 밀린 요소입니다. 연속해서 여러 번 터졌다면 사실 일 필요는 없습니다.
— user127.0.0.1

1
@ user127.0.0.1 : 각 팝이 끝날 때 큐를 전환하는 것을 잊어 버린 것 같습니다. 각 푸시 및 각 팝 후에는 모든 항목이 queue1에 있고 queue2는 비어있는 것은 변하지 않습니다.
— Svante

68

이 작업을 수행하는 가장 쉬운 방법은 새 요소를 빈 대기열로 푸시 한 다음 다른 요소를 대기열에서 빼고 이전의 빈 대기열로 대기열에 넣는 것입니다. 이 방법으로 최신은 항상 대기열의 맨 앞에 있습니다. 이것은 버전 B입니다. 버전 A의 경우 마지막 큐를 제외하고 요소를 두 번째 큐로 큐에서 빼서 프로세스를 반대로합니다.

0 단계 :

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

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

1 단계:

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

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

2 단계:

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

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

3 단계 :

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

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

1
이것에 대한 논리는 의미가 없습니다. 2 단계에서 3 단계로 이동하십시오. 3을 "누르면"큐 A에서 3 2 1을 얻는 방식으로 큐 B의 요소를 큐에서 제거하는 방법은 무엇입니까? B를 대기열에 넣고 A를 대기열에 넣으면 순서 2, 1의 요소 만 가져올 수 있습니다. 그런 다음 3을 추가하면 순서 3, 1, 2가 표시됩니다. 1, 2, 3.
— tsurantino

인큐 작업을 비싸게 만드는 것보다 deque 작업을 비싸게 만드는 이유는 무엇입니까?
— Divij Sehgal

49

하나의 대기열 로이 작업을 수행 할 수 있습니다.

푸시:

  1. 새로운 요소를 큐에 넣습니다.
  2. n큐의 요소 수인 경우 요소 n-1시간 을 제거하고 삽입하십시오 .

팝:

  1. 대기열에서 빼다

.

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

샘플 구현 :

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

누구나 위의 코드에서 push 메소드 뒤에 로그인을 설명 할 수 있습니까? 내가 이해하는 한, 첫 번째 for 루프는 q1에 하나의 요소가 남을 때까지 모든 요소를 ​​q2로 제거합니다. 내가 틀렸다면 정정 해주세요.
— John

4

하나의 대기열을 사용하여 스택을 구현할 수 있습니까? 두 개의 대기열을 사용할 수 있지만 단일 대기열을 고려하는 것이 더 효율적입니다. 코드는 다음과 같습니다.

    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 메소드에서는 0으로 변수 i를 초기화 할 때 for 루프 조건이 i <queLower.Count-2 여야한다고 생각 합니다.
— 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

내 대답은 '팝'이 비효율적 인 곳입니다. 즉시 생각 나는 모든 알고리즘에는 N 복잡성이 있습니다. 여기서 N은 목록의 크기입니다. '팝'에 대한 작업을 선택하든 '푸시'에 대한 작업을 선택하든

크기를 계산할 필요가 없기 때문에 목록을 다시 교환하고 네 번째로 교환하는 알고리즘이 더 나을 수 있습니다. 빈과 비교하고 반복해야합니다.

큐의 마지막 요소에 대한 정보는 큐의 크기를 알아야만 사용할 수 있으며 해당 요소에 도달하기 위해 데이터를 삭제해야하므로 두 번째 큐에이 알고리즘을 N보다 빠르게 작성할 수 없음을 증명할 수 있습니다. .

이를보다 빠르게하는 유일한 방법은 우선 대기열을 사용하지 않는 것입니다.

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

다음은 평균 경우 O (1)에서 작동하는 솔루션입니다. 두 개의 대기열이 있습니다 : in및 out. 의사 코드 아래를 참조하십시오.

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
거기에서 2 개의 대기열과 1 개의 스택을 사용하여 1 개의 스택을 시뮬레이션합니다!
— BeniBela

재귀 스택을 의미합니까?
— Vladimir Kostyukov

1

언급했듯이 단일 대기열이 트릭을 수행하지 않습니까? 아마 실용적이지는 않지만 약간 더 칙칙합니다.

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

pop(x):
dequeue()

1

다음은 간단한 의사 코드입니다. 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

S1과 S2를 대기열 구현에 사용되는 두 스택으로 둡니다.

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

우리는 하나의 큐가 항상 비어 있는지 확인합니다.

푸시 조작 : 비어 있지 않은 큐에 요소를 삽입하십시오.

  • 큐 Q1이 비어 있는지 확인하십시오. Q1이 비어 있으면 요소를 큐에 넣습니다.
  • 그렇지 않으면 요소를 Q1에 대기열에 넣습니다.

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

시간 복잡성 : O (1)

팝 조작 : n-1 요소를 다른 큐로 전송하고 팝 조작을 수행하기 위해 큐에서 마지막으로 삭제하십시오.

  • 큐 Q1이 비어 있지 않으면 n-1 요소를 Q1에서 Q2로 전송 한 다음 Q1의 마지막 요소를 큐에 대기시키고 리턴하십시오.
  • 큐 Q2가 비어 있지 않으면 n-1 요소를 Q2에서 Q1로 전송 한 다음 Q2의 마지막 요소를 큐에 대기시켜 리턴하십시오.

`

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

시간 복잡성 : 팝의 실행 시간 팝이 호출 될 때마다 작업이 O (n)입니다. 모든 요소를 ​​한 큐에서 다른 큐로 전송합니다.


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

하나 더 해결책이 있습니다.

PUSH의 경우 :-큐 1에 첫 번째 요소 추가-두 번째 요소 등을 추가 할 때 큐 2의 요소를 먼저 큐에 넣은 후 큐 1에서 큐 2로 모든 요소를 ​​복사하십시오. -POP의 경우 마지막 요소를 삽입 한 큐에서 요소를 큐에서 빼십시오.

그래서,

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

하나의 문제가 있는데, 대기열 이름을 바꾸는 방법을 알 수 없습니다. ??


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
이 코드가 무엇인지 설명하고이 문제가 OP가 자신의 문제를 해결하는 데 어떻게 도움이 될 수 있는지 설명하는 몇 가지 단어를 코드 예제와 함께 높이 평가하겠습니다. :-)
— nIcE cOw

0

하나의 대기열 만 사용하는 Python 코드

 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
답변으로 코드를 덤프하지 말고 코드의 기능과 이유를 설명하십시오. 관련 코딩 경험이없는 사람들에게는 코드가 명확하지 않을 수 있습니다.
— Frits

0

다음은 C #의 완전한 작업 코드입니다.

단일 대기열로 구현되었습니다.

푸시:

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

팝:

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

현재 유지 / 누르고있는 요소의 기능으로 구현에 필요한 (예상 / 아마존) 시간에 대해 언급하고 있습니까?
— greybeard

0

다음은 하나의 대기열을 사용하고 스택과 같은 기능을 제공하는 매우 간단한 솔루션입니다.

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


}

따라서 위의 클래스 "CustomStack"에서 내가하고있는 것은 비어있는 대기열을 확인한 다음 비어 있으면 삽입 한 다음 그다음 삽입을 삽입 한 다음 삽입을 제거하는 것입니다. 이 논리에 의해 가장 먼저 올 것이다. 예 : 대기열에 1을 삽입하고 이제 2를 삽입하려고합니다. 두 번째로 1을 제거한 다음 다시 삽입하여 역순으로하십시오.

감사합니다.


0

아래는 푸시 작업을 효율적으로 지원하는 매우 간단한 Java 솔루션입니다.

알고리즘-

  1. 두 개의 큐 q1 및 q2를 선언하십시오.

  2. 푸시 조작-큐 요소를 큐에 대기 q1.

  3. 팝 조작-큐 q2가 비어 있지 않은지 확인하십시오. 비어 있으면 마지막 요소를 제외한 q1에서 모든 요소를 ​​큐에서 빼고 q2에 하나씩 큐에 넣습니다. q1에서 마지막 요소를 대기열에서 빼고 팝된 요소로 저장하십시오. 큐 q1과 q2를 교환하십시오. 저장된 팝 요소를 반환합니다.

  4. 엿보기 조작-큐 q2가 비어 있지 않은지 확인하십시오. 비어 있으면 마지막 요소를 제외한 q1에서 모든 요소를 ​​큐에서 빼고 q2에 하나씩 큐에 넣습니다. q1에서 마지막 요소를 대기열에서 빼고 엿보기 요소로 저장하십시오. 큐 q2로 다시 큐잉하고 큐 q1 및 q2를 교환하십시오. 저장된 피킹 된 요소를 반환합니다.

아래는 위 알고리즘에 대한 코드입니다.

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

여기 내 해결책이 있습니다 ..

Concept_Behind :: push(struct Stack* S,int data)::이 함수는 Q1에서 첫 번째 요소를 대기열에 넣고 Q2에서 휴식 pop(struct Stack* S) Q2가 비어 있지 않으면 모든 요소를 ​​Q1로 전송하고 Q2의 마지막 요소를 반환합니다 (그렇지 않으면 Q2가 비어 있음). Q1의 마지막 요소를 반환

Efficiency_Behind :: push(struct Stack*S,int data)::: 데이터 당 단일 대기열 이후 :: O (1) // pop(struct Stack* S): :: O (n) // since는 팝당 최악의 n-1 데이터를 전송합니다.

#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 링크 목록은 deque처럼 잘 작동합니다. 이 답변은 의미가 없습니다.
— 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;
}

주석이나 설명이없는 코드 벽은 나쁜 대답입니다.
— Richard
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.