使用队列实现堆栈
问题与这篇文章相反。我们得到了一个队列数据结构,它支持像 enqueue() 和 dequeue() 这样的标准操作。我们需要仅使用 Queue 的实例和实例上允许的队列操作来实现 Stack 数据结构。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。
一个堆栈可以使用两个队列来实现。让要实现的堆栈为“s”,用于实现的队列为“q1”和“q2”。 Stack 's' 可以通过两种方式实现:
方法 1(通过使推送操作成本高昂)
此方法确保新输入的元素始终位于 'q1' 的前面,因此 pop 操作只是从 'q1' 出列。 'q2' 用于将每个新元素放在 'q1' 的前面。
- push(s, x)操作的步骤描述如下:
- 将 x 加入 q2
- 将 q1 中的所有内容逐一出列并入队到 q2。
- 交换 q1 和 q2 的名称
- 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 中出列并返回。
- push(s, x)操作:
- 将 x 加入 q1(假设 q1 的大小是无限的)。
- 弹出操作:
- 将 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