算法与数据结构——一些特殊的栈总结【有序的栈、能返回栈中最小元素的栈、队列与栈的相互转化问题】(Java)

有序的栈

image-20220712163833581

类似单调栈的结构

辅助栈要求规则是从栈底到栈顶是从大到小的

每次从栈中弹出一个数尝试加入到辅助栈中,如果符合规则就直接加入,不符合规则就一直弹出辅助栈压回到主栈中直到该数字能加入到辅助栈中

当主栈空的时候辅助栈就是有序的

再把辅助栈的数一次性全部倒入回主栈,此时主栈就是有序的

public void sortStack(Stack<Integer> stack){
    Stack<Integer> help=new Stack<>();
    while(!stack.isEmpty()){
        int pre=stack.pop();
        while(!help.isEmpty()&&help.peek()<pre){
            stack.push(help.pop());
        }
        help.push(pre);
    }
    while(!help.isEmpty()){
        stack.push(help.pop());
    }
}

特殊的栈

image-20220716103722599

准备两个栈

一个是普通的栈

另外一个栈:进元素时看当前元素和栈顶元素,谁小压谁

这样就做到了每弹出一个元素时知道当前栈中的最小值是谁

public class Mystack{
    private Stack<Integer> dataStack;
    private Stack<Integer> minStack;
    
    public Mystack(){
        dataStack=new Stack<>();
        minStack=new Stack<>();
    }
    
    public void push(int newNum){
        if(this.minStack.empty()){
            this.minStack.push(newNum);
        }else if(newNum<minStack.peek()){
            this.minStack.push(newNum);
        }else{
            int newMin=this.minStack.peek();
            this.minStack.push(newMin);
        }
        this.dataStack.push(newNum);
    }
    
    public int pop(){
        if(this.dataStack.empty()){
            throw new RuntimeException("Your stack is Empty");
        }
        this.minStack.pop();
        return this.dataStack.pop();
    }
    
    public int getMin(){
        if(this.minStack.empty()){
            throw new RuntimeException("Your stack is Empty");
        }
        return this.minStack.peek();
    }
}

结构转化

image-20220716104926399

如何仅用队列结构实现栈结构

准备两个队列

进来的元素全部加到队列一中

当需要弹出的时候把队列一的除末尾的数全部加入到队列二中 把末尾的数弹出返回即可 再把两个队列的数据状况做交换即可

public class queueToStack{
    private Queue<Integer> queue;
    private Queue<Integer> help;

    public TwoQueuesStack() {
        queue = new LinkedList<Integer>();
        help = new LinkedList<Integer>();
    }
    
    public void push(int num){
        queue.add(num);
    }
    
    public int peek(){
        if(queue.isEmpty()){
            throw new RuntimeException("Stack is Empty");
        }
        while(queue.size()!=1){
            help.add(queue.pop());
        }
        int res=queue.poll();
        help.add(res);
        swap();
        return res;
    }
    
    public void swap(){
        Queue<Integer> tmp=help;
        help=queue;
        queue=tmp;
    }
    
    public int pop(){
        if(queue.isEmpty()){
            throw new RuntimeException("Stack is Empty");
        }
        while(queue.size()!=1){
            help.add(queue.pop());
        }
        int res=queue.poll();
        swap();
        return res;
    }
}

如何仅用栈结构实现队列结构

准备两个栈

先把全部元素加入到push栈中

全部导入pop栈中

pop栈弹出的结果就是队列要求的顺序

public class StackToQueue{
    private Stack<Integer> pushStack;
    private Stack<Integer> popStack;
    
    public StackToQueue(){
        pushStack=new Stack<>();
        popStack=new Stack<>();
    }
    
    public void push(int num){
        pushSatck.push(num);
        convert();//做任何操作时都看一下能不能倒
    }
    
    public int poll(){
        if(popStack.empty()&&pushStack.empty()){
            throw new RuntimeException("Your stack is Empty");
        }
        convert();//做任何操作时都看一下能不能倒
        return popStack.pop();
    }
    
    public int peek(){
        if(popStack.empty()&&pushStack.empty()){
            throw new RuntimeException("Your stack is Empty");
        }
        convert();//做任何操作时都看一下能不能倒
    }
    
    public void convert(){
        if(popStack.isEmpty()){//只有pop栈为空时才倒
            while(!pushStack.isEmpty()){
                popStack.push(pushSatck.pop());
            }
        }
    }
}

题目:用栈实现图的宽度优先遍历等其实就是在考察栈与队列之间的转化

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值