假设我们有两个堆栈,没有其他临时变量。

是否有可能“构造”一个队列数据结构只使用两个堆栈?


当前回答

这是我的解决方案在Java使用链表。

class queue<T>{
    static class Node<T>{
        private T data;
        private Node<T> next;
        Node(T data){
            this.data = data;
            next = null;
        }
    }
    Node firstTop;
    Node secondTop;
    
    void push(T data){
        Node temp = new Node(data);
        temp.next = firstTop;
        firstTop = temp;
    }
    
    void pop(){
        if(firstTop == null){
            return;
        }
        Node temp = firstTop;
        while(temp != null){
            Node temp1 = new Node(temp.data);
            temp1.next = secondTop;
            secondTop = temp1;
            temp = temp.next;
        }
        secondTop = secondTop.next;
        firstTop = null;
        while(secondTop != null){
            Node temp3 = new Node(secondTop.data);
            temp3.next = firstTop;
            firstTop = temp3;
            secondTop = secondTop.next;
        }
    }
    
}

注意:在这种情况下,弹出操作非常耗时。因此,我不建议使用两个堆栈创建队列。

其他回答

对于c#开发人员,这里是完整的程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QueueImplimentationUsingStack
{
    class Program
    {
        public class Stack<T>
        {
            public int size;
            public Node<T> head;
            public void Push(T data)
            {
                Node<T> node = new Node<T>();
                node.data = data;
                if (head == null)
                    head = node;
                else
                {
                    node.link = head;
                    head = node;
                }
                size++;
                Display();
            }
            public Node<T> Pop()
            {
                if (head == null)
                    return null;
                else
                {
                    Node<T> temp = head;
                    //temp.link = null;
                    head = head.link;
                    size--;
                    Display();
                    return temp;
                }
            }
            public void Display()
            {
                if (size == 0)
                    Console.WriteLine("Empty");
                else
                {
                    Console.Clear();
                    Node<T> temp = head;
                    while (temp!= null)
                    {
                        Console.WriteLine(temp.data);
                        temp = temp.link;
                    }
                }
            }
        }

        public class Queue<T>
        {
            public int size;
            public Stack<T> inbox;
            public Stack<T> outbox;
            public Queue()
            {
                inbox = new Stack<T>();
                outbox = new Stack<T>();
            }
            public void EnQueue(T data)
            {
                inbox.Push(data);
                size++;
            }
            public Node<T> DeQueue()
            {
                if (outbox.size == 0)
                {
                    while (inbox.size != 0)
                    {
                        outbox.Push(inbox.Pop().data);
                    }
                }
                Node<T> temp = new Node<T>();
                if (outbox.size != 0)
                {
                    temp = outbox.Pop();
                    size--;
                }
                return temp;
            }

        }
        public class Node<T>
        {
            public T data;
            public Node<T> link;
        }

        static void Main(string[] args)
        {
            Queue<int> q = new Queue<int>();
            for (int i = 1; i <= 3; i++)
                q.EnQueue(i);
           // q.Display();
            for (int i = 1; i < 3; i++)
                q.DeQueue();
            //q.Display();
            Console.ReadKey();
        }
    }
}

保持2个堆栈,让我们称之为收件箱和发件箱。

排队:

将新元素推到收件箱上

出列:

如果发件箱为空,则通过弹出收件箱中的每个元素并将其推入发件箱来重新填充它 弹出并返回发件箱中的顶部元素

使用这种方法,每个元素只在每个堆栈中存在一次——这意味着每个元素将被压入两次,弹出两次,从而给出平摊常数时间操作。

下面是Java中的实现:

public class Queue<E>
{

    private Stack<E> inbox = new Stack<E>();
    private Stack<E> outbox = new Stack<E>();

    public void queue(E item) {
        inbox.push(item);
    }

    public E dequeue() {
        if (outbox.isEmpty()) {
            while (!inbox.isEmpty()) {
               outbox.push(inbox.pop());
            }
        }
        return outbox.pop();
    }

}

我的PHP解决方案

<?php
$_fp = fopen("php://stdin", "r");
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
    $queue = array();
    $count = 0;
    while($line = fgets($_fp)) {
        if($count == 0) {
            $noOfElement = $line;
            $count++;
            continue;
        }
        $action = explode(" ",$line);
        $case = $action[0];
        switch($case) {
            case 1:
                $enqueueValue = $action[1];
                array_push($queue, $enqueueValue);
                break;
            case 2:
                array_shift($queue);
                break;
            case 3:
                $show = reset($queue);
                print_r($show);
                break;
            default:
                break;
        }
    }
?>

简单的JS解决方案**

注:我从其他人的评论中获得了一些想法

/* enQueue(q, x) 1) Push x to stack1 (assuming size of stacks is unlimited). deQueue(q) 1) If both stacks are empty then error. 2) If stack2 is empty While stack1 is not empty, push everything from stack1 to stack2. 3) Pop the element from stack2 and return it. */ class myQueue { constructor() { this.stack1 = []; this.stack2 = []; } push(item) { this.stack1.push(item) } remove() { if (this.stack1.length == 0 && this.stack2.length == 0) { return "Stack are empty" } if (this.stack2.length == 0) { while (this.stack1.length != 0) { this.stack2.push(this.stack1.pop()) } } return this.stack2.pop() } peek() { if (this.stack2.length == 0 && this.stack1.length == 0) { return 'Empty list' } if (this.stack2.length == 0) { while (this.stack1.length != 0) { this.stack2.push(this.stack1.pop()) } } return this.stack2[0] } isEmpty() { return this.stack2.length === 0 && this.stack1.length === 0; } } const q = new myQueue(); q.push(1); q.push(2); q.push(3); q.remove() console.log(q)

这是我的解决方案在Java使用链表。

class queue<T>{
    static class Node<T>{
        private T data;
        private Node<T> next;
        Node(T data){
            this.data = data;
            next = null;
        }
    }
    Node firstTop;
    Node secondTop;
    
    void push(T data){
        Node temp = new Node(data);
        temp.next = firstTop;
        firstTop = temp;
    }
    
    void pop(){
        if(firstTop == null){
            return;
        }
        Node temp = firstTop;
        while(temp != null){
            Node temp1 = new Node(temp.data);
            temp1.next = secondTop;
            secondTop = temp1;
            temp = temp.next;
        }
        secondTop = secondTop.next;
        firstTop = null;
        while(secondTop != null){
            Node temp3 = new Node(secondTop.data);
            temp3.next = firstTop;
            firstTop = temp3;
            secondTop = secondTop.next;
        }
    }
    
}

注意:在这种情况下,弹出操作非常耗时。因此,我不建议使用两个堆栈创建队列。