每日一题算法:2020年6月30日 用两个栈实现队列 CQueue

2020年6月30日 用两个栈实现队列 CQueue

在这里插入图片描述

默认格式:

class CQueue {

    public CQueue() {

    }
    
    public void appendTail(int value) {

    }
    
    public int deleteHead() {

    }
}

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue obj = new CQueue();
 * obj.appendTail(value);
 * int param_2 = obj.deleteHead();
 */

解题思路:

首先,我们要用两个栈,栈就是先入后出。然后我们要做成一个队列,队列是先入先出,那要怎么把两个先入后出的结构变成先入先出的结构呢?

先写一个栈的数据结构。

class Node{

    Node son;
    int val;
    Node(int num){
        this.val=num;
    }

}


class Stack{

    Node head;

    void push(int val){
       Node node= new Node(val);
        if (head==null){
            head=node;
            return;
        }

        node.son=head;
        head=node;

    }

    int pop(){
    
        if (head==null)
            return -1;
        int val=head.val;
        head=head.son;
        return val;

    }

}

方式1

插入之前先将栈中所有元素出栈到另一个栈中,然后直接插在栈底,并且把另一个栈中的元素移回来

在这里插入图片描述

第一步,栈1依次出栈到栈2中
在这里插入图片描述

4如栈1
在这里插入图片描述

栈2出栈回到栈1
在这里插入图片描述

这么做有一个很大的问题,操作一个数字需要操作整个栈两次,很浪费时间。

优化:

用一个栈专门负责入栈,一个栈专门负责出栈。

这样在连续的入栈的操作时,可以不用操作另一个栈,出栈也是同理。

这样做的话,有一个栈会一直是空的。

出栈:2和3

在这里插入图片描述
在这里插入图片描述

然后连续入栈5、6

先把3,4换过去
在这里插入图片描述

直到出栈操作之前,不需要取出栈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-McK0oaXL-1593523101147)(C:%5CUsers%5CAdmin%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20200630205304959.png)]

代码实现:
在这里插入图片描述

package month6;

import org.junit.Test;

public class CQueue {

    Stack stack1;
    Stack stack2;


    public CQueue() {
        stack1=new Stack();
        stack2=new Stack();
    }

    public void appendTail(int value) {

        //如果栈1为空,说明当前是入栈操作
        if (stack1.head==null){
            stack2.push(value);
        }
        //否则,把栈1的都移动出到栈2中
        else
        {
            while (stack1.head!=null){
                stack2.push(stack1.pop());
            }
            stack2.push(value);
        }
    }

    public int deleteHead() {
       if (stack2.head==null){
            return stack1.pop();
        }
        else
        {
            while (stack2.head!=null){
                stack1.push(stack2.pop());
            }
            return stack1.pop();
        }
    }
}
class Node{

    Node son;
    int val;
    Node(int num){
        this.val=num;
    }

}


class Stack{

    Node head;

    void push(int val){
       Node node= new Node(val);
        if (head==null){
            head=node;
            return;
        }

        node.son=head;
        head=node;

    }

    int pop(){

        if (head==null)
            return -1;
        int val=head.val;
        head=head.son;
        return val;

    }

}

最终优化:

看了官方的解答,发现自己还有一些没想到的点,实际上插入并不需要将栈2中的元素都取出,可以暂时先存在栈1中,这样取的时候也不需要将栈1的元素移动回去,直到栈2空了,在将栈1的元素给移过来
在这里插入图片描述

class CQueue {
    
    //stack1负责出栈
    Stack stack1;
    //stack2负责入栈
    Stack stack2;


    public CQueue() {
        stack1=new Stack();
        stack2=new Stack();
    }

    public void appendTail(int value) {

            stack2.push(value);
        
    }

public int deleteHead() {
       if (stack1.head==null){
           while (stack2.head!=null){
               stack1.push(stack2.pop());
           }
           return stack1.pop();
        }
        else
        {

            return stack1.pop();
        }
    }
    class Node{

    Node son;
    int val;
    Node(int num){
        this.val=num;
    }

}


class Stack{

    Node head;

    void push(int val){
       Node node= new Node(val);
        if (head==null){
            head=node;
            return;
        }

        node.son=head;
        head=node;

    }

    int pop(){

        if (head==null)
            return -1;
        int val=head.val;
        head=head.son;
        return val;

    }

}
}

展开阅读全文
©️2020 CSDN 皮肤主题: 游动-白 设计师: 上身试试 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值