Java~栈与队列的应用(利用栈实现队列、利用队列是实现栈)

在学习完栈和队列后,栈的特征是先进后出,队列的特征是先进先出,因此可以利用该性质,利用两个栈实现队列的操作,利用两个队列实现栈的操作。 

目录

利用栈实现队列

初始化 

入队列 

判断队列是否为空

弹出队头元素 

获取队头元素 

栈实现队列完整代码 

利用队列实现栈 

初始化 

判断栈是否为空

入栈操作 

出栈操作 

获取栈顶元素 

队列实现栈完整代码 


利用栈实现队列

队列的定义:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的性质。入队列:进行插入操作的一端称为队尾;出队列:进行删除操作的一端称为队头

队列中有哪些方法?

如何利用栈实现队列 ?

需要定义出两个栈来实现队列,首先将要存入的元素放入第一个栈stack1中,当要出队时,就将stack1中的元素出栈存入到stack2中,则此时stack2的出栈顺序即为队列的出队顺序.

 

初始化 

初始化两个栈,stack1和stack2,stack1主要用来入队操作,stack2用来实现出队操作

public class MyQueue {
    Stack<Integer> stack1;
    Stack<Integer> stack2;

    //构造方法
    public MyQueue() {
        this.stack1 = new Stack<>();
        this.stack2 = new Stack<>();
    }
    
}

入队列 

入队操作统一将元素存入stack1中,存入后如下图所示

具体代码: 

    //入队操作
    public void push(int x) {
        this.stack1.push(x);
    }

判断队列是否为空

队列判空操作只需要判断两个栈是否都为空即可. 

    //队列是否为空
    public boolean empty() {
        return stack1.empty() && stack2.empty();
    }

弹出队头元素 

要弹出队头元素,需要将stack1中的元素按照栈的出栈顺序存入到stack2中,此时stack2中的出栈顺序即为队列的出队顺序,具体如下图所示:

注意: 在将stack1中元素存储stack2的过程中,一定是出栈操作,而不能是取栈顶元素操作。

    //弹出队头元素
    public int pop() {
        if(empty()) {
            return -1;
        }
        if(stack2.empty()) {
            while(!stack1.empty()) {
                int val = stack1.pop();
                stack2.push(val);

            }
        }
        return stack2.pop();
    }

获取队头元素 

获取队头元素依旧是将stack1中元素出栈存入stack2中,如果之后还需要将元素入队,则直接插入栈stack中,但不对stack2进行操作,只有当stack2为空时,再将栈stack1中元素出栈插入到栈stack2中.

    //获取队头元素
    public int peek() {
        if(empty()) {
            return -1;
        }
        if(stack2.empty()) {
            while(!stack1.empty()) {
                int val = stack1.pop();
                stack2.push(val);
            }
        }
        return stack2.peek();
    }

栈实现队列完整代码 

import java.util.*;

public class MyQueue {
    Stack<Integer> stack1;
    Stack<Integer> stack2;

    //构造方法
    public MyQueue() {
        this.stack1 = new Stack<>();
        this.stack2 = new Stack<>();
    }

    //入队操作
    public void push(int x) {
        this.stack1.push(x);
    }

    //弹出队头元素
    public int pop() {
        if(empty()) {
            return -1;
        }
        if(stack2.empty()) {
            while(!stack1.empty()) {
                int val = stack1.pop();
                stack2.push(val);

            }
        }
        return stack2.pop();
    }

    //获取队头元素
    public int peek() {
        if(empty()) {
            return -1;
        }
        if(stack2.empty()) {
            while(!stack1.empty()) {
                int val = stack1.pop();
                stack2.push(val);
            }
        }
        return stack2.peek();
    }

    //队列是否为空
    public boolean empty() {
        return stack1.empty() && stack2.empty();
    }
}

利用队列实现栈 

 栈的定义:栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入或删除的一端称为栈顶,另一端称为栈底。栈中的元素遵循后进先出(先进后出)原则。压栈:栈的插入操作称为压栈/进栈/入栈,入栈在栈顶进行;出栈:栈的删除操作称为出栈,出栈在栈顶进行.

栈中有哪些方法?

如何利用队列实现栈?

创建两个队列,que1和que2,每次进行入栈时将元素存入为空的一个队列中,当要进行出栈或者取栈顶元素操作时,首先将非空队列中Size - 1个元素入队至当前为空的队列中,之后非空队列剩下的元素即为栈顶元素.

初始化 

创建两个队列que1和que2来实现栈的操作

public class MyStack {
    private Queue<Integer> que1;
    private Queue<Integer> que2;

    //构造方法
    public MyStack() {
        que1 = new LinkedList<>();
        que2 = new LinkedList<>();
    }
}

判断栈是否为空

只需判断两个队列是否都为空,若都为空,则栈为空.

    //判断栈是否为空
    public boolean isEmpty() {
        if(que1.isEmpty() && que2.isEmpty()) {
            return true;
        }
        return false;
    }

入栈操作 

在进行入栈操作前,需要判断两个队列哪个为空,将要入栈的元素插入到不为空的那个队列中,如果两个队列都为空,默认插入到第一个队列que1中.

例如下图,目前栈中已经存入1、2、3,若要继续存入4,则需判断哪个栈不为空,将其插入至不为空的栈中.

    //入栈操作
    public void pop(int x) {
        if(!que1.isEmpty()) {
            que1.offer(x);
        } else if (!que2.isEmpty()) {
            que2.offer(x);
        } else {
            //当两个队列都为空时,默认放到第一个队列中
            que1.offer(x);
        }
    }

出栈操作 

要进行出栈操作,首先将非空队列中的size-1个元素入队至第二个队列中,如下图所示:

之后que1中剩余的一个元素即为栈顶元素,将该元素出队即可实现栈的出栈操作. 

    //出栈操作
    public int pop() {
        if(isEmpty()) {
            return -1;
        }
        if(!que1.isEmpty()) {
            int size = que1.size();
            for (int i = 0; i < size-1; i++) {
                int x = que1.poll();
                que2.offer(x);
            }
            //返回剩下的元素
            return que1.poll();
        } else {
            int size = que2.size();
            for (int i = 0; i < size-1; i++) {
                int x = que2.poll();
                que1.offer(x);
            }
            //返回剩下的元素
            return que2.poll();
        }
    }

获取栈顶元素 

利用队列实现获取栈顶元素操作与出栈操作基本思想一致,只不过获取栈顶元素操作未将元素删除,而是保存下来后返回.

如下图所示:

此时x保存的数据即为栈顶元素,返回该元素即可. 

    //获取栈顶元素
    public int top() {
        if(isEmpty()) {
            return -1;
        }
        if(!que1.isEmpty()) {
            int size = que1.size();
            int x = -1;
            for (int i = 0; i < size; i++) {
                x = que1.poll();
                que2.offer(x);
            }
            //返回剩下的元素
            return x;
        } else {
            int size = que2.size();
            int x = -1;
            for (int i = 0; i < size; i++) {
                x = que2.poll();
                que1.offer(x);
            }
            //返回剩下的元素
            return x;
        }
    }

队列实现栈完整代码 

import java.util.LinkedList;
import java.util.Queue;

public class MyStack {
    private Queue<Integer> que1;
    private Queue<Integer> que2;

    //构造方法
    public MyStack() {
        que1 = new LinkedList<>();
        que2 = new LinkedList<>();
    }

    //判断栈是否为空
    public boolean isEmpty() {
        if(que1.isEmpty() && que2.isEmpty()) {
            return true;
        }
        return false;
    }

    //入栈操作
    public void pop(int x) {
        if(!que1.isEmpty()) {
            que1.offer(x);
        } else if (!que2.isEmpty()) {
            que2.offer(x);
        } else {
            //当两个队列都为空时,默认放到第一个队列中
            que1.offer(x);
        }
    }

    //出栈操作
    public int pop() {
        if(isEmpty()) {
            return -1;
        }
        if(!que1.isEmpty()) {
            int size = que1.size();
            for (int i = 0; i < size-1; i++) {
                int x = que1.poll();
                que2.offer(x);
            }
            //返回剩下的元素
            return que1.poll();
        } else {
            int size = que2.size();
            for (int i = 0; i < size-1; i++) {
                int x = que2.poll();
                que1.offer(x);
            }
            //返回剩下的元素
            return que2.poll();
        }
    }

    //获取栈顶元素
    public int top() {
        if(isEmpty()) {
            return -1;
        }
        if(!que1.isEmpty()) {
            int size = que1.size();
            int x = -1;
            for (int i = 0; i < size; i++) {
                x = que1.poll();
                que2.offer(x);
            }
            //返回剩下的元素
            return x;
        } else {
            int size = que2.size();
            int x = -1;
            for (int i = 0; i < size; i++) {
                x = que2.poll();
                que1.offer(x);
            }
            //返回剩下的元素
            return x;
        }
    }
}

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li_yizYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值