Java数据结构 ---- 栈和队列

一.栈

栈的内容相对简单,java中用顺序表实现栈,除栈外双向链表也可以实现栈, 栈只有pop,push,peek,empty方法,直接刷题

1. 有效括号序列

public class Solution {
    /**
     * 
     * @param s string字符串 
     * @return bool布尔型
     */
    public boolean isValid (String s) {
        // write code here\
        char c;
        Stack<Character> eg = new Stack<>();

        for (int i = 0; i < s.length(); i ++){
            c = s.charAt(i);
            if (c == '(' || c == '[' || c == '{'){
                eg.push(c);
            }else{
                if (eg.empty()){
                    return false;
                }else{
                    char a = eg.peek();
                    if(a == '(' && c == ')' || a == '[' && c == ']' || a == '{' && c == '}'){
                        eg.pop();
                    }else{
                        return false;
                    }
                }
            }
        }
        return eg.empty();
    }

2. 表达式求值

在这里插入图片描述

import java.util.*;
public class Solution {
    public int solve1 (char ch, int a, int b) {
        switch (ch) {
            case '+':
                return b + a;
            case '-':
                return b - a;
            case '*':
                return b * a;
        }
        return 0;
    }

    public int solve (String s) {
        // write code here
        Stack<Character> stack1 = new Stack<>();
        Stack<Integer> stack2 = new Stack<>();
        char ch;
        int i = 0;
        String s1 = "";
        short flag1 = 0;
        short flag2 = 0;
        while (i < s.length()) {
            ch = s.charAt(i);
            if (!stack1.empty() && stack1.peek() == '*'){
                flag1 = 1;
            }
            if ( ch == ')') {
                while (stack1.peek() != '(') {
                    int eg = solve1(stack1.pop(), stack2.pop(), stack2.pop());
                    stack2.push(eg);
                }
                stack1.pop();
                    if (flag1 == 1 && flag2 >0){
                    flag2--;
                }
                i++;
            } else {
                s1 = "";
                while (ch != '+'  && ch != '*' && ch != '-' && ch != '(' && ch != ')') {
                    if (i < s.length() - 1) {
                        s1 += ch;
                        ch = s.charAt(++i);
                    } else if (i == s.length() - 1) {
                        s1 += ch;
                        i++;
                    } 
                    if (i == s.length()) {
                        break;
                    }
                }
                if (s1 != "") {
                    stack2.push(Integer.parseInt(s1));
                }
                if (flag1 == 1 && ch == '(' ){
                    flag2++;
                }
                if (flag1 == 1 && flag2 == 0 && !stack1.empty()){
                    int eg = solve1(stack1.pop(), stack2.pop(), stack2.pop());
                    stack2.push(eg);
                    flag1 = 0;
                }

                if (ch == '+' || ch == '*' || ch == '(' || ch == '-') {
                    stack1.push(ch);
                    i++;
                }
            }
        }
        while (!stack1.empty() ) {
            char eg1 = stack1.pop();
            if (!stack1.empty() && stack1.peek() == '-') {
                if (eg1 == '-')
                eg1 = '+';
                else
                eg1 = '-';
            }
            int eg2 = solve1(eg1, stack2.pop(), stack2.pop());
            stack2.push(eg2);
        }
        return stack2.pop();
    }
}

二. 队列

java中用双向链表来实现队列,用单链表也可以实现队列,但是入队必须用尾插,出队必须用从头出
另外用顺序表也可以实现队列,但为了空间利用,用顺序表实现的是循环队列
循环队列需要解决两个问题,第一如何判断队列是满是空,第二如何实现数组满后对头和队尾在同一位置.(也就是如何从8位置到1位置)

Queue是一个接口,必须用LinkedList来实例化,因为LinkedList实现了Queue接口

在这里插入图片描述

1. 用数组模拟实现循环队列

需要注意的是,入队列时,队尾下标不能是单纯的加1;
出队列时,队头下标不能是单纯的加1;
访问队尾元素时,不能单纯的返回element[rear - 1], 而要判断当前队尾是否为0

import java.util.Arrays;
public class circularQueue {
    private int[] element;
    private int front = 0;
    private int rear  = 0;
    public circularQueue(int i){
        this.element = new int[i];
    }
    public boolean enQueue(int value){
        if (isfull()){
            this.element = Arrays.copyOf(this.element, 2  * this.element.length);
        }
        element[rear] = value;
        rear = (rear + 1) % element.length;
        return true;
    }
    public boolean deQueue(){
        if (isEmpty()){
            System.out.println("队列为空,不可出队");
            return false;
        }else{
            this.front = (this.front + 1) % this.element.length;
            return true;
        }
    }
    public int Front(){
        if (isEmpty()){
            System.out.print("当前队列为空" + " ");
            return -1;
        }
        return this.element[this.front];
    }
    public int Rear(){
        if (isEmpty()){
            System.out.print("当前队列为空" + " ");
            return -1;
        }
        int index = this.rear == 0 ? this.element.length - 1 : this.rear - 1;
        return this.element[index];
    }
    public boolean isfull(){
        return ((this.rear + 1) % this.element.length == this.front);
    }
    public boolean isEmpty(){
        return this.front == this.rear;
    }
}

在这里插入图片描述

2. 双端队列

两端都可以进队或出队,此时的队列必须用双向链表来实现,java中的队列就是用双向链表来实现的

3. 刷题

3.1 用两个队列实现一个栈

需要注意的是入栈和获取栈顶元素时,将元素转移到空队列中时,for循环中的结束条件不能是queue.size(),因为在出队时size会发生变化,需用一个数来记录size值,这里出bug的几率极大

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

public class queue {
    private Queue<Integer> queue1;
    private Queue<Integer> queue2;
    public queue(){
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }
    public void push(int valu){
        if (!queue1.isEmpty()){
            queue1.offer(valu);
        }else if (!queue2.isEmpty()){
            queue2.offer(valu);
        }else{
            queue1.offer(valu);
        }
    }
    public int pop(){
        if (!queue1.isEmpty()){
            int length = queue1.size();
            for(int i = 0; i < length - 1; i++){
                queue2.offer(queue1.poll());
            }
            return queue1.poll();
        }else if (!queue2.isEmpty()){
            int length = queue2.size();
            for(int i = 0; i < length - 1; i++){
                queue1.offer(queue2.poll());
            }
            return queue2.poll();
        }else{
            System.out.print("当前栈为空, 出栈操作失败");
            return -1;
        }
    }
    public int peek(){
        int eg = 0;
        if (!queue1.isEmpty()){
            int length = queue1.size();
            for(int i = 0; i < length; i++){
                eg = queue1.poll();
                queue2.offer(eg);
            }
            return eg;
        }else if (!queue2.isEmpty()){
            int length = queue2.size();
            for(int i = 0; i < length; i++){
                eg = queue2.poll();
                queue1.offer(eg);
            }
            return eg;
        }else{
            System.out.print("当前栈为空, 查询栈顶元素失败");
            return -1;
        }
    }
    public boolean empty(){
        return queue1.isEmpty() && queue2.isEmpty();
    }
}

3.2 用两个栈实现一个队列

import java.util.Stack;
public class MyQueue {
    private Stack<Integer> stack1;
    private Stack<Integer> stack2;
    public MyQueue(){
        stack1 = new Stack();
        stack2 = new Stack();
    }
    public void offer(int valu){
        stack1.push(valu);

    }
    public int poll(){
        if(isEmply()){
            System.out.print("当前队列为空,出队操作失败");
            return -1;
        }
        if(stack2.empty()){
            int length = stack1.size();
            for(int i = 0; i < length; i++){
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }
    public int peek(){
        if(isEmply()){
            System.out.print("当前队列为空,获取对尾元素操作失败");
            return -1;
        }
        if(stack2.empty()){
            int length = stack1.size();
            for(int i = 0; i < length; i++){
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();
    }
    public boolean isEmply(){
        return stack1.empty() && stack2.empty();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

With Order @!147

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

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

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

打赏作者

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

抵扣说明:

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

余额充值