📜  使用队列实现堆栈

📅  最后修改于: 2022-05-13 01:57:00.918000             🧑  作者: Mango

使用队列实现堆栈

问题与这篇文章相反。我们得到了一个队列数据结构,它支持像 enqueue() 和 dequeue() 这样的标准操作。我们需要仅使用 Queue 的实例和实例上允许的队列操作来实现 Stack 数据结构。

带有插入和删除操作的堆栈和队列

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。



一个堆栈可以使用两个队列来实现。让要实现的堆栈为“s”,用于实现的队列为“q1”和“q2”。 Stack 's' 可以通过两种方式实现:
方法 1(通过使推送操作成本高昂)
此方法确保新输入的元素始终位于 'q1' 的前面,因此 pop 操作只是从 'q1' 出列。 'q2' 用于将每个新元素放在 'q1' 的前面。

  1. push(s, x)操作的步骤描述如下:
    • 将 x 加入 q2
    • 将 q1 中的所有内容逐一出列并入队到 q2。
    • 交换 q1 和 q2 的名称
  2. pop(s)操作的函数描述如下:
    • 从 q1 出列一个项目并返回它。

下面是上述方法的实现:

C++
/* Program to implement a stack using
two queue */
#include 
 
using namespace std;
 
class Stack {
    // Two inbuilt queues
    queue q1, q2;
 
    // To maintain current number of
    // elements
    int curr_size;
 
public:
    Stack()
    {
        curr_size = 0;
    }
 
    void push(int x)
    {
        curr_size++;
 
        // Push x first in empty q2
        q2.push(x);
 
        // Push all the remaining
        // elements in q1 to q2.
        while (!q1.empty()) {
            q2.push(q1.front());
            q1.pop();
        }
 
        // swap the names of two queues
        queue q = q1;
        q1 = q2;
        q2 = q;
    }
 
    void pop()
    {
 
        // if no elements are there in q1
        if (q1.empty())
            return;
        q1.pop();
        curr_size--;
    }
 
    int top()
    {
        if (q1.empty())
            return -1;
        return q1.front();
    }
 
    int size()
    {
        return curr_size;
    }
};
 
// Driver code
int main()
{
    Stack s;
    s.push(1);
    s.push(2);
    s.push(3);
 
    cout << "current size: " << s.size()
         << endl;
    cout << s.top() << endl;
    s.pop();
    cout << s.top() << endl;
    s.pop();
    cout << s.top() << endl;
 
    cout << "current size: " << s.size()
         << endl;
    return 0;
}
// This code is contributed by Chhavi


Java
/* Java Program to implement a stack using
two queue */
import java.util.*;
 
class GfG {
 
    static class Stack {
        // Two inbuilt queues
        static Queue q1 = new LinkedList();
        static Queue q2 = new LinkedList();
 
        // To maintain current number of
        // elements
        static int curr_size;
 
        Stack()
        {
            curr_size = 0;
        }
 
        static void push(int x)
        {
            curr_size++;
 
            // Push x first in empty q2
            q2.add(x);
 
            // Push all the remaining
            // elements in q1 to q2.
            while (!q1.isEmpty()) {
                q2.add(q1.peek());
                q1.remove();
            }
 
            // swap the names of two queues
            Queue q = q1;
            q1 = q2;
            q2 = q;
        }
 
        static void pop()
        {
 
            // if no elements are there in q1
            if (q1.isEmpty())
                return;
            q1.remove();
            curr_size--;
        }
 
        static int top()
        {
            if (q1.isEmpty())
                return -1;
            return q1.peek();
        }
 
        static int size()
        {
            return curr_size;
        }
    }
 
    // driver code
    public static void main(String[] args)
    {
        Stack s = new Stack();
        s.push(1);
        s.push(2);
        s.push(3);
 
        System.out.println("current size: " + s.size());
        System.out.println(s.top());
        s.pop();
        System.out.println(s.top());
        s.pop();
        System.out.println(s.top());
 
        System.out.println("current size: " + s.size());
    }
}
// This code is contributed by Prerna


Python3
# Program to implement a stack using
# two queue
from queue import Queue
 
class Stack:
     
    def __init__(self):
         
        # Two inbuilt queues
        self.q1 = Queue()
        self.q2 = Queue()
             
        # To maintain current number
        # of elements
        self.curr_size = 0
 
    def push(self, x):
        self.curr_size += 1
 
        # Push x first in empty q2
        self.q2.put(x)
 
        # Push all the remaining
        # elements in q1 to q2.
        while (not self.q1.empty()):
            self.q2.put(self.q1.queue[0])
            self.q1.get()
 
        # swap the names of two queues
        self.q = self.q1
        self.q1 = self.q2
        self.q2 = self.q
 
    def pop(self):
 
        # if no elements are there in q1
        if (self.q1.empty()):
            return
        self.q1.get()
        self.curr_size -= 1
 
    def top(self):
        if (self.q1.empty()):
            return -1
        return self.q1.queue[0]
 
    def size(self):
        return self.curr_size
 
# Driver Code
if __name__ == '__main__':
    s = Stack()
    s.push(1)
    s.push(2)
    s.push(3)
 
    print("current size: ", s.size())
    print(s.top())
    s.pop()
    print(s.top())
    s.pop()
    print(s.top())
 
    print("current size: ", s.size())
 
# This code is contributed by PranchalK


C#
/* C# Program to implement a stack using
two queue */
using System;
using System.Collections;
 
class GfG {
 
    public class Stack {
        // Two inbuilt queues
        public Queue q1 = new Queue();
        public Queue q2 = new Queue();
 
        // To maintain current number of
        // elements
        public int curr_size;
 
        public Stack()
        {
            curr_size = 0;
        }
 
        public void push(int x)
        {
            curr_size++;
 
            // Push x first in empty q2
            q2.Enqueue(x);
 
            // Push all the remaining
            // elements in q1 to q2.
            while (q1.Count > 0) {
                q2.Enqueue(q1.Peek());
                q1.Dequeue();
            }
 
            // swap the names of two queues
            Queue q = q1;
            q1 = q2;
            q2 = q;
        }
 
        public void pop()
        {
 
            // if no elements are there in q1
            if (q1.Count == 0)
                return;
            q1.Dequeue();
            curr_size--;
        }
 
        public int top()
        {
            if (q1.Count == 0)
                return -1;
            return (int)q1.Peek();
        }
 
        public int size()
        {
            return curr_size;
        }
    };
 
    // Driver code
    public static void Main(String[] args)
    {
        Stack s = new Stack();
        s.push(1);
        s.push(2);
        s.push(3);
        Console.WriteLine("current size: " + s.size());
        Console.WriteLine(s.top());
        s.pop();
        Console.WriteLine(s.top());
        s.pop();
        Console.WriteLine(s.top());
        Console.WriteLine("current size: " + s.size());
    }
}
 
// This code is contributed by Arnab Kundu


C++
/* Program to implement a stack
using two queue */
#include 
using namespace std;
 
class Stack {
    queue q1, q2;
    int curr_size;
 
public:
    Stack()
    {
        curr_size = 0;
    }
 
    void pop()
    {
        if (q1.empty())
            return;
 
        // Leave one element in q1 and
        // push others in q2.
        while (q1.size() != 1) {
            q2.push(q1.front());
            q1.pop();
        }
 
        // Pop the only left element
        // from q1
        q1.pop();
        curr_size--;
 
        // swap the names of two queues
        queue q = q1;
        q1 = q2;
        q2 = q;
    }
 
    void push(int x)
    {
        q1.push(x);
        curr_size++;
    }
 
    int top()
    {
        if (q1.empty())
            return -1;
 
        while (q1.size() != 1) {
            q2.push(q1.front());
            q1.pop();
        }
 
        // last pushed element
        int temp = q1.front();
 
        // to empty the auxiliary queue after
        // last operation
        q1.pop();
 
        // push last element to q2
        q2.push(temp);
 
        // swap the two queues names
        queue q = q1;
        q1 = q2;
        q2 = q;
        return temp;
    }
 
    int size()
    {
        return curr_size;
    }
};
 
// Driver code
int main()
{
    Stack s;
    s.push(1);
    s.push(2);
    s.push(3);
    s.push(4);
 
    cout << "current size: " << s.size()
         << endl;
    cout << s.top() << endl;
    s.pop();
    cout << s.top() << endl;
    s.pop();
    cout << s.top() << endl;
    cout << "current size: " << s.size()
         << endl;
    return 0;
}
// This code is contributed by Chhavi


Java
/* Java Program to implement a stack
using two queue */
import java.util.*;
 
class Stack {
    Queue q1 = new LinkedList<>(), q2 = new LinkedList<>();
    int curr_size;
 
    public Stack()
    {
        curr_size = 0;
    }
 
    void remove()
    {
        if (q1.isEmpty())
            return;
 
        // Leave one element in q1 and
        // push others in q2.
        while (q1.size() != 1) {
            q2.add(q1.peek());
            q1.remove();
        }
 
        // Pop the only left element
        // from q1
        q1.remove();
        curr_size--;
 
        // swap the names of two queues
        Queue q = q1;
        q1 = q2;
        q2 = q;
    }
 
    void add(int x)
    {
        q1.add(x);
        curr_size++;
    }
 
    int top()
    {
        if (q1.isEmpty())
            return -1;
 
        while (q1.size() != 1) {
            q2.add(q1.peek());
            q1.remove();
        }
 
        // last pushed element
        int temp = q1.peek();
 
        // to empty the auxiliary queue after
        // last operation
        q1.remove();
 
        // push last element to q2
        q2.add(temp);
 
        // swap the two queues names
        Queue q = q1;
        q1 = q2;
        q2 = q;
        return temp;
    }
 
    int size()
    {
        return curr_size;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        Stack s = new Stack();
        s.add(1);
        s.add(2);
        s.add(3);
        s.add(4);
 
        System.out.println("current size: " + s.size());
        System.out.println(s.top());
        s.remove();
        System.out.println(s.top());
        s.remove();
        System.out.println(s.top());
        System.out.println("current size: " + s.size());
    }
}
 
// This code is contributed by Princi Singh


Python3
# Program to implement a stack using
# two queue
from queue import Queue
 
 
class Stack:
 
    def __init__(self):
 
        # Two inbuilt queues
        self.q1 = Queue()
        self.q2 = Queue()
 
        # To maintain current number
        # of elements
        self.curr_size = 0
 
    def push(self, x):
        self.q1.put(x)
        self.curr_size += 1
 
    def pop(self):
        # if no elements are there in q1
        if (self.q1.empty()):
            return
        # Leave one element in q1 and push others in q2
        while(self.q1.qsize() != 1):
            self.q2.put(self.q1.get())
 
        # Pop the only left element from q1
        popped = self.q1.get()
        self.curr_size -= 1
 
        # swap the names of two queues
        self.q = self.q1
        self.q1 = self.q2
        self.q2 = self.q
 
    def top(self):
        # if no elements are there in q1
        if (self.q1.empty()):
            return
        # Leave one element in q1 and push others in q2
        while(self.q1.qsize() != 1):
            self.q2.put(self.q1.get())
 
        # Pop the only left element from q1 to q2
        top = self.q1.queue[0]
        self.q2.put(self.q1.get())
 
        # swap the names of two queues
        self.q = self.q1
        self.q1 = self.q2
        self.q2 = self.q
 
        return top
 
    def size(self):
        return self.curr_size
 
 
# Driver Code
if __name__ == '__main__':
    s = Stack()
    s.push(1)
    s.push(2)
    s.push(3)
    s.push(4)
 
    print("current size: ", s.size())
    print(s.top())
    s.pop()
    print(s.top())
    s.pop()
    print(s.top())
 
    print("current size: ", s.size())
 
# This code is contributed by jainlovely450


C#
using System;
using System.Collections;
class GfG
{
    public class Stack
    {
        public Queue q1 = new Queue();
        public Queue q2 = new Queue();
        //Just enqueue the new element to q1
        public void Push(int x) => q1.Enqueue(x);
 
        //move all elements from q1 to q2 except the rear of q1.
        //Store the rear of q1
        //swap q1 and q2
        //return the stored result
        public int Pop()
        {
            if (q1.Count == 0)
                return -1;
            while (q1.Count > 1)
            {
                q2.Enqueue(q1.Dequeue());
            }
            int res = (int)q1.Dequeue();
            Queue temp = q1;
            q1 = q2;
            q2 = temp;
            return res;
        }
 
        public int Size() => q1.Count;
 
        public int Top()
        {
            if (q1.Count == 0)
                return -1;
            while (q1.Count > 1)
            {
                q2.Enqueue(q1.Dequeue());
            }
            int res = (int)q1.Dequeue();
            q2.Enqueue(res);
            Queue temp = q1;
            q1 = q2;
            q2 = temp;
            return res;
        }
    };
    public static void Main(String[] args)
    {
        Stack s = new Stack();
    s.Push(1);
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
    s.Push(7);
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
    s.Push(9);
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
 
    s.Pop();
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
    s.Pop();
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
 
    s.Push(5);
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
    }
}
//Submitted by Sakti Prasad
 
//Size of Stack: 1 Top : 1
//Size of Stack: 2 Top : 7
//Size of Stack: 3 Top : 9
//Size of Stack: 2 Top : 7
//Size of Stack: 1 Top : 1
//Size of Stack: 2 Top : 5


输出 :

current size: 3
3
2
1
current size: 1

方法 2(通过使 pop 操作成本高昂)
在推送操作中,新元素总是排队到 q1。在 pop() 操作中,如果 q2 为空,则除最后一个元素外的所有元素都移动到 q2。最后,最后一个元素从 q1 中出列并返回。

  1. push(s, x)操作:
    • 将 x 加入 q1(假设 q1 的大小是无限的)。
  2. 弹出操作:
    • 将 q1 中除最后一个元素之外的所有元素逐一出列并入队到 q2。
    • 将q1的最后一项出列,出列的项为result,存储。
    • 交换 q1 和 q2 的名称
    • 返回在步骤 2 中存储的项目。

C++

/* Program to implement a stack
using two queue */
#include 
using namespace std;
 
class Stack {
    queue q1, q2;
    int curr_size;
 
public:
    Stack()
    {
        curr_size = 0;
    }
 
    void pop()
    {
        if (q1.empty())
            return;
 
        // Leave one element in q1 and
        // push others in q2.
        while (q1.size() != 1) {
            q2.push(q1.front());
            q1.pop();
        }
 
        // Pop the only left element
        // from q1
        q1.pop();
        curr_size--;
 
        // swap the names of two queues
        queue q = q1;
        q1 = q2;
        q2 = q;
    }
 
    void push(int x)
    {
        q1.push(x);
        curr_size++;
    }
 
    int top()
    {
        if (q1.empty())
            return -1;
 
        while (q1.size() != 1) {
            q2.push(q1.front());
            q1.pop();
        }
 
        // last pushed element
        int temp = q1.front();
 
        // to empty the auxiliary queue after
        // last operation
        q1.pop();
 
        // push last element to q2
        q2.push(temp);
 
        // swap the two queues names
        queue q = q1;
        q1 = q2;
        q2 = q;
        return temp;
    }
 
    int size()
    {
        return curr_size;
    }
};
 
// Driver code
int main()
{
    Stack s;
    s.push(1);
    s.push(2);
    s.push(3);
    s.push(4);
 
    cout << "current size: " << s.size()
         << endl;
    cout << s.top() << endl;
    s.pop();
    cout << s.top() << endl;
    s.pop();
    cout << s.top() << endl;
    cout << "current size: " << s.size()
         << endl;
    return 0;
}
// This code is contributed by Chhavi

Java

/* Java Program to implement a stack
using two queue */
import java.util.*;
 
class Stack {
    Queue q1 = new LinkedList<>(), q2 = new LinkedList<>();
    int curr_size;
 
    public Stack()
    {
        curr_size = 0;
    }
 
    void remove()
    {
        if (q1.isEmpty())
            return;
 
        // Leave one element in q1 and
        // push others in q2.
        while (q1.size() != 1) {
            q2.add(q1.peek());
            q1.remove();
        }
 
        // Pop the only left element
        // from q1
        q1.remove();
        curr_size--;
 
        // swap the names of two queues
        Queue q = q1;
        q1 = q2;
        q2 = q;
    }
 
    void add(int x)
    {
        q1.add(x);
        curr_size++;
    }
 
    int top()
    {
        if (q1.isEmpty())
            return -1;
 
        while (q1.size() != 1) {
            q2.add(q1.peek());
            q1.remove();
        }
 
        // last pushed element
        int temp = q1.peek();
 
        // to empty the auxiliary queue after
        // last operation
        q1.remove();
 
        // push last element to q2
        q2.add(temp);
 
        // swap the two queues names
        Queue q = q1;
        q1 = q2;
        q2 = q;
        return temp;
    }
 
    int size()
    {
        return curr_size;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        Stack s = new Stack();
        s.add(1);
        s.add(2);
        s.add(3);
        s.add(4);
 
        System.out.println("current size: " + s.size());
        System.out.println(s.top());
        s.remove();
        System.out.println(s.top());
        s.remove();
        System.out.println(s.top());
        System.out.println("current size: " + s.size());
    }
}
 
// This code is contributed by Princi Singh

蟒蛇3

# Program to implement a stack using
# two queue
from queue import Queue
 
 
class Stack:
 
    def __init__(self):
 
        # Two inbuilt queues
        self.q1 = Queue()
        self.q2 = Queue()
 
        # To maintain current number
        # of elements
        self.curr_size = 0
 
    def push(self, x):
        self.q1.put(x)
        self.curr_size += 1
 
    def pop(self):
        # if no elements are there in q1
        if (self.q1.empty()):
            return
        # Leave one element in q1 and push others in q2
        while(self.q1.qsize() != 1):
            self.q2.put(self.q1.get())
 
        # Pop the only left element from q1
        popped = self.q1.get()
        self.curr_size -= 1
 
        # swap the names of two queues
        self.q = self.q1
        self.q1 = self.q2
        self.q2 = self.q
 
    def top(self):
        # if no elements are there in q1
        if (self.q1.empty()):
            return
        # Leave one element in q1 and push others in q2
        while(self.q1.qsize() != 1):
            self.q2.put(self.q1.get())
 
        # Pop the only left element from q1 to q2
        top = self.q1.queue[0]
        self.q2.put(self.q1.get())
 
        # swap the names of two queues
        self.q = self.q1
        self.q1 = self.q2
        self.q2 = self.q
 
        return top
 
    def size(self):
        return self.curr_size
 
 
# Driver Code
if __name__ == '__main__':
    s = Stack()
    s.push(1)
    s.push(2)
    s.push(3)
    s.push(4)
 
    print("current size: ", s.size())
    print(s.top())
    s.pop()
    print(s.top())
    s.pop()
    print(s.top())
 
    print("current size: ", s.size())
 
# This code is contributed by jainlovely450

C#

using System;
using System.Collections;
class GfG
{
    public class Stack
    {
        public Queue q1 = new Queue();
        public Queue q2 = new Queue();
        //Just enqueue the new element to q1
        public void Push(int x) => q1.Enqueue(x);
 
        //move all elements from q1 to q2 except the rear of q1.
        //Store the rear of q1
        //swap q1 and q2
        //return the stored result
        public int Pop()
        {
            if (q1.Count == 0)
                return -1;
            while (q1.Count > 1)
            {
                q2.Enqueue(q1.Dequeue());
            }
            int res = (int)q1.Dequeue();
            Queue temp = q1;
            q1 = q2;
            q2 = temp;
            return res;
        }
 
        public int Size() => q1.Count;
 
        public int Top()
        {
            if (q1.Count == 0)
                return -1;
            while (q1.Count > 1)
            {
                q2.Enqueue(q1.Dequeue());
            }
            int res = (int)q1.Dequeue();
            q2.Enqueue(res);
            Queue temp = q1;
            q1 = q2;
            q2 = temp;
            return res;
        }
    };
    public static void Main(String[] args)
    {
        Stack s = new Stack();
    s.Push(1);
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
    s.Push(7);
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
    s.Push(9);
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
 
    s.Pop();
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
    s.Pop();
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
 
    s.Push(5);
    Console.WriteLine("Size of Stack: " + s.Size() + "\tTop : " + s.Top());
    }
}
//Submitted by Sakti Prasad
 
//Size of Stack: 1 Top : 1
//Size of Stack: 2 Top : 7
//Size of Stack: 3 Top : 9
//Size of Stack: 2 Top : 7
//Size of Stack: 1 Top : 1
//Size of Stack: 2 Top : 5

输出 :

current size: 4
4
3
2
current size: 2