数据结构&算法Java版(二) 栈&队列

欢迎关注我的B站账号:卍卍子非鱼卍卍

栈&队列

栈节点StackNode

class StackNode<T> {
    public T val;
    public StackNode<T> next;

    public StackNode() {
        this(null);
    }

    public StackNode(T val) {
        this.val = val;
        this.next = null;
    }
}

栈类型MyStack

boolean isEmpty() 判断栈是否为空

void push(T e) 元素进栈

T pop() 栈顶元素出栈

T peek() 取栈顶元素

String toString() 打印栈

class MyStack<T> {
    StackNode<T> head;

    public MyStack() {
        head = new StackNode<T>();
    }

    // 判断栈是否为空
    public boolean isEmpty() {
        return head.next == null;
    }

    // 元素进栈
    public void push(T e) {
        StackNode<T> p = new StackNode<T>(e);
        p.next = head.next;
        head.next = p;
    }

    // 栈顶元素出栈
    public T pop() {
        if (this.isEmpty()) {
            throw new NullPointerException();
        }
        T val = head.next.val;
        head.next = head.next.next;
        return val;
    }

    // 取栈顶元素
    public T peek() {
        if (this.isEmpty()) {
            throw new NullPointerException();
        }
        T val = head.next.val;
        return val;
    }

    // 打印栈
    public String toString() {
        if (this.isEmpty()) {
            return "";
        }
        String str = "";
        StackNode<T> node = head;
        while (node.next.next != null) {
            node = node.next;
            str += node.val + "->";
        }
        str += node.next.val;
        return str;
    }
}

队列

队列节点QueueNode

class QueueNode<T> {
    public T val;
    public QueueNode<T> next;

    public QueueNode() {
        this(null);
    }

    public QueueNode(T val) {
        this.val = val;
        this.next = null;
    }
}

队列类型MyQueue

boolean isEmpty() 判断队列是否为空

void offer(T e) 元素进队

T poll() 元素出队

T element() 取队首元素

String toString() 打印队列

class MyQueue<T> {
    QueueNode<T> head;
    QueueNode<T> tail;

    public MyQueue() {
        head = null;
        tail = null;
    }

    // 判断队列是否为空
    public boolean isEmpty() {
        return tail == null;
    }

    // 元素进队
    public void offer(T e) {
        QueueNode<T> node = new QueueNode<T>(e);
        if (this.isEmpty()) {
            head = node;
            tail = node;
        } else {
            tail.next = node;
            tail = tail.next;
        }
    }

    // 元素出队
    public T poll() {
        if (this.isEmpty()) {
            throw new NullPointerException();
        }
        T val = head.val;
        if (head == tail) {
            head = null;
            tail = null;
        } else {
            head = head.next;
        }
        return val;
    }

    // 取队首元素
    public T element() {
        if (this.isEmpty()) {
            throw new NullPointerException();
        }
        return head.val;
    }

    // 打印队列
    public String toString() {
        if (this.isEmpty()) {
            return "";
        }
        QueueNode<T> node = head;
        String str = "[";
        while (node.next != null) {
            str += node.val + ", ";
            node = node.next;
        }
        str += node.val + "]";
        return str;
    }
}

中缀表达式转后缀表达式

输入中缀表达式字符串形式,输出后缀表达式数组形式

算法思路

后缀表达式:又名逆波兰式,运算符写在操作数之后

中缀表达式:按照正常写法的计算式

现有如下中缀表达式:“(56 + 20) / (2 * 4)”

将其转化为后缀表达式的数组形式:["56", "20", "+", "2", "4", "*", "/"]

思路如下:

1.定义List<String> suffix用于存储中缀表达式, 定义MyStack<String> stack用于暂时存储运算符

2.从左到右以字符ch形式读取字符串:

2.1 若ch为数字,一直读取直到不是数字为止,将该数字加入suffix

2.2 若ch(,将(进栈到stack

2.3 若ch),将stack中的元素依次出栈并加入suffix,直到栈顶元素为(,然后将(出栈

2.4 若ch+-,将stack中的元素依次出栈并加入suffix,直到栈顶元素为(或栈空,然后将ch进栈

2.5 若ch*/,将stack中的元素依次出栈并加入suffix,直到栈顶元素为(+-或栈空,然后将ch进栈

3.字符串读取完毕后,将stack中的元素依次出栈并加入suffix

以表达式“(56 + 20) / (2 * 4)”为例,最后后缀表达式形式:["56", "20", "+", "2", "4", "*", "/"]

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

代码

import java.util.*;

class Solution_1 {
    /**
     * 中缀表达式转后缀表达式
     * 
     * @param Infix 中缀表达式
     * @return 后缀表达式的数组形式
     */
    public String[] InfToSuf(String infix) {
        List<String> suffix = new ArrayList<String>();
        MyStack<String> stack = new MyStack<String>();
        for (int i = 0; i < infix.length(); i++) {
            int j = i + 1;
            String regex = "^-?\\d+$";
            while (j <= infix.length() && infix.substring(i, j).matches(regex)) {
                j++;
            }
            if (j > i + 1) {
                String num = infix.substring(i, j - 1);
                suffix.add(num);
                i = j - 2;
            } else {
                String str = infix.substring(i, i + 1);
                switch (str) {
                    case "(":
                        stack.push(str);
                        break;
                    case ")":
                        while (!stack.peek().equals("(")) {
                            suffix.add(stack.pop());
                        }
                        stack.pop();
                        break;
                    case "+":
                    case "-":
                        while (!stack.isEmpty() && !stack.peek().equals("(")) {
                            suffix.add(stack.pop());
                        }
                        stack.push(str);
                        break;
                    case "*":
                    case "/":
                        while (!stack.isEmpty() && !stack.peek().equals("(") && !stack.peek().equals("+")
                                && !stack.peek().equals("-")) {
                            suffix.add(stack.pop());
                        }
                        stack.push(str);
                        break;
                }
            }
        }
        while (!stack.isEmpty()) {
            suffix.add(stack.pop());
        }
        String[] array = new String[suffix.size()];
        suffix.toArray(array);
        return array;
    }
}

后缀表达式求值

输入后缀表达式的数组形式,输出求得的值(整数形式)

算法思路

现有上一题求出的后缀表达式数组形式suffix["56", "20", "+", "2", "4", "*", "/"]

计算它的值

思路如下:

1.定义MyStack<Integer> stack用作临时存储

2.以字符串str形式遍历suffix

2.1 若str为数字,将str入栈

2.2 若str为运算符op(其中op可以表示"+","-","*","/"),连续出栈两个数值a,b,计算b op a,并入栈

3.遍历结束,返回栈顶元素stack.peek()

以后缀表达式["56", "20", "+", "2", "4", "*", "/"]为例:
在这里插入图片描述
在这里插入图片描述

代码

class Solution_2 {
    /**
     * 后缀表达式求值
     * 
     * @param suffix 后缀表达式的数组形式
     * @return 求得的值(整数形式)
     */
    public int evalSuf(String[] suffix) {
        MyStack<Integer> stack = new MyStack<Integer>();
        String regex = "^-?\\d+$";
        for (String str : suffix) {
            if (str.matches(regex)) {
                stack.push(Integer.parseInt(str));
            } else {
                int num1 = stack.pop(), num2 = stack.pop();
                switch (str) {
                    case "+":
                        num2 += num1;
                        break;
                    case "-":
                        num2 -= num1;
                        break;
                    case "*":
                        num2 *= num1;
                        break;
                    case "/":
                        num2 /= num1;
                        break;
                }
                stack.push(num2);
            }
        }
        return stack.pop();
    }
}

验证回文串

输入待验证的字符串,是回文串返回true,否则返回false

算法思路

回文串特征:从左到右读与从右到左读各个字符相同

如:aabbaa是回文串,aaaa是回文串,abcabc不是回文串

思路如下:

1.定义MyStack<Character> stack用于存储字符

2.以字符ch形式顺序读取字符串str,将ch入栈

3.将栈内元素依次出栈,并与顺序读取的字符ch比较,若两者不相等,说明不是回文串,返回false

4.栈空说明所有字符均满足回文串特征,返回true

代码

class Solution_3 {
    /**
     * 验证字符串是否为回文串
     * 
     * @param str 待验证的字符串
     * @return 是回文串返回true,否则返回false
     */
    public boolean isPalindrome(String str) {
        MyStack<Character> stack = new MyStack<Character>();
        for (char ch : str.toCharArray()) {
            stack.push(ch);
        }
        for (char ch : str.toCharArray()) {
            if (ch != stack.pop()) {
                return false;
            }
        }
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值