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


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 QueuesPop$ 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)에서 작동하는 솔루션입니다. 두 개의 대기열이 있습니다 : inout. 의사 코드 아래를 참조하십시오.

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.