栈和队列的简单运用

栈和队列

1.根据入栈出栈规律,判断顺序是否合理

实现思路:

直接使用栈试错,其中inOutOrder为原始数据,outOrder为需要判断的顺序,inOutOrder根据outOrder判断入栈出栈规则

    public boolean isOutOrder(int[] inOutOrder, int[] outOrder) {
        if (inOutOrder == null || outOrder == null || inOutOrder.length != outOrder.length) {
            return false;
        }//判断边界值
        Stack<Integer> stack = new Stack<>();
        int i = 0, j = 0;//i用于inOutOrder遍历,j用于outOrder的遍历
        while (i < inOutOrder.length - 1) {
            if (stack.isEmpty()) {
                stack.push(inOutOrder[i++]);
            }//判断stack是否为null,为null时,需要进栈
            while (outOrder[j] != stack.peek() && i != inOutOrder.length) {
                stack.push(inOutOrder[i++]);
            }//前者判断最顶上的数据与outOrder数组中的数组是否相等,后者为了控制边界值(即i不会越界)
            while (outOrder[j] == stack.peek()) {
                stack.pop();
                j++;
                if (j == outOrder.length - 1) {
                    return true;
                }//当outOrder中所有数据都试错过之后那么自然返回true
                if (stack.isEmpty()) {
                    stack.push(inOutOrder[i++]);
                }//依旧为了控制边界值,当所有数据全部弹出后,inOutOrder之后的数据入栈
            }
        }
        return false;//当i已经超过inOutOrder数组范围,明显栈弹出规律为false
    }

2.用栈结构实现队列结构

实现思路:

应该注意两个栈相互导数据的时机,比如

stackPush中有数据,就直接倒入stackPop

poll() 执行之前应把所有数据倒入stackPop

add() 之前需要stackPop中没有数据

public class TwoStackQueue<T> {
    Stack<T> stackPush;
    Stack<T> stackPop;

    public TwoStackQueue() {
        this.stackPush = new Stack<>();
        this.stackPop = new Stack<>();
    }

    public void PushToPop() {//该方法用于stackPush往stackPop中导数据
        if (stackPop.isEmpty()) {//此时将stackPush中的所有数据都倒入stackPop
            while (!stackPush.isEmpty()) {
                stackPop.push(stackPush.pop());
            }
        }
    }

    public void add(T value) {
        stackPush.push(value);//先把数据存入stackPush
        PushToPop();//将存入的数倒入stackPop
    }

    public T poll() {
        if (stackPush.isEmpty() && stackPop.isEmpty()) {
            throw new RuntimeException("栈空!");
        }
        PushToPop(); //弹出之前需要保证stackPush中没有数据
        return stackPop.pop();
    }

    public T peek(){
        if (stackPop.isEmpty() && stackPush.isEmpty()){
            throw new RuntimeException("栈空!");
        }
        PushToPop(); //查看之前需要保证stackPush中没有数据
        return stackPop.peek();
    }
}

3.用队列结构实现栈结构

实现思路:

模拟入栈:添加数据时,往有数据的那个队列插入数据

模拟出栈:将有数据的那个队列中数据全导入另一个队列,直到只剩下一个数据为止,把最后剩下的数据返回并删除,模拟队列出栈

public class TwoQueueStack<T> {
    LinkedList<T> q1;//使用链表模拟队列,采用头插尾删法
    LinkedList<T> q2;

    public TwoQueueStack() {
        q1 = new LinkedList<>();
        q2 = new LinkedList<>();
    }

    public void add(T value) {//添加数据时,往有数据的那个队列插入数据
        if (!q1.isEmpty()) {
            q1.addFirst(value);
        } else {
            q2.addFirst(value);
        }
    }

    public T poll() {
        if (q1.isEmpty() && q2.isEmpty()) {//判断两个队列是否都为空,都为空的话,抛出队列空异常
            throw new RuntimeException("队空!");
        }
        if (!q1.isEmpty() && q2.isEmpty()) {
            while (q1.size() > 1) {//将有数据的那个队列中数据全导入另一个队列,直到只剩下一个数据为止
                q2.addFirst(q1.removeLast());
            }
            return q1.removeFirst();//把最后剩下的数据返回并删除,模拟队列出栈
        }
        if (q1.isEmpty() && !q2.isEmpty()) {
            while (q2.size() > 1) {
                q1.addFirst(q2.removeLast());
            }
            return q2.removeFirst();
        }
        return null;
    }

}

4.实现一个具有getMin功能的栈

实现思路:

使用两个栈,一个原始数据栈stackData,一个最小值栈stackMin

pubs时,当stackMin为空时,直接将这个值压入栈,当value小于时,压入这个值,当大于等于stackMin栈顶元素时,压入栈顶元素

pop时,两个栈同时弹出,返回stackData栈顶元素

getMin时,直接返回stackMin栈顶元素

public class MyStack {
    Stack<Integer> stackData;
    Stack<Integer> stackMin;

    public MyStack() {
        this.stackData = new Stack<>();
        this.stackMin = new Stack<>();
    }

    public void pubs(int value) {
        if (stackMin.isEmpty()) {//栈为空时,直接把这个数压入栈中
            stackMin.push(value);
        } else if (value < stackMin.peek()) {//如果这个数比最小数栈顶小,压入这个数
            stackMin.push(value);
        } else {//剩下的就是比最小数栈顶大于或等于的,那么直接压入栈顶元素
            stackMin.push(stackMin.peek());
        }
        stackData.push(value);//data栈同步压入
    }

    public int pop() {
        if (stackMin.isEmpty()) {//判断边界值
            throw new RuntimeException("栈空!");
        }
        stackMin.pop();//两个栈同步弹出,data栈栈顶元素返回
        return stackData.pop();
    }

    public int getMin() {
        if (stackMin.isEmpty()) {
            throw new RuntimeException("栈空!");
        }
        return stackMin.peek();//返回最小值栈顶值

    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值