数据结构:栈及其应用

栈的初步认识

在这里插入图片描述

栈的设计

Stack接口

因为栈可以用顺序存储实现也可以用链式存储实现,所以把共性抽取定义出Stack接口
在这里插入图片描述

ArrayStack类(栈的顺序存储具体实现)

因为栈本身是一种特殊的线性表,所以我们可以用上一篇博客中完成的ArrayList来实现我们的ArrayStack

public class ArrayStack<E> implements Stack<E> {
    
    
    //栈的内部用线性表来实现
    private ArrayList<E> list;

    /**
     * 创建默认容量的线性表
     */
    public ArrayStack(){
    
    
        list=new ArrayList<E>();
    }

    /**
     * 创建指定容量的线性表
     * @param capacity
     */
    public ArrayStack(int capacity){
    
    
        list=new ArrayList<>(capacity);
    }

    /**
     * 获取线性表中元素个数
     * @return
     */
    @Override
    public int size() {
    
    
        return list.size();
    }

    /**
     * 判断栈是否为空
     * @return
     */
    @Override
    public boolean isEmpty() {
    
    
        return list.isEmpty();
    }

    /**
     * 压栈,在表尾添加
     * @param element
     */
    @Override
    public void push(E element) {
    
    
        list.add(element);
    }

    /**
     * 弹栈一个元素并且返回(在线性表的末尾删除一个元素并且返回)
     * @return
     */
    @Override
    public E pop() {
    
    
        return list.remove(list.size()-1);
    }

    /**
     * 查看当前栈顶元素(不删除)
     * @return
     */
    @Override
    public E peek() {
    
    
        return list.get(list.size()-1);
    }

    /**
     * 清空栈
     */
    @Override
    public void clear() {
    
    
        list.clear();
    }

    @Override
    public Iterator<E> iterator() {
    
    
        return list.iterator();
    }

    @Override
    public String toString() {
    
    
        StringBuilder builder = new StringBuilder(String.format("ArrayStack:%d/%d[", size(),list.getCapacity()));
        if (isEmpty()) {
    
    
            builder.append("]");//ArrayList:0/10;

        } else {
    
    
            for (int i = 0; i < size(); i++) {
    
    
                builder.append(list.get(i));
                if (i != size() - 1) {
    
    
                    builder.append(",");
                } else {
    
    
                    builder.append("]");
                }
            }
        }
        return builder.toString();
    }
}

在这里插入图片描述

十进制和十六进制的互相转换

十进制转为十六进制

在这里插入图片描述

public class DecToHex {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入一个十进制数:");
        int num=scanner.nextInt();
        /**
         * 因为会涉及到数字和字母,比如A,B这样的,所以泛型应该是Charcater
         * 创建一个栈来存储余数
         */
        ArrayStack<Character> stack=new ArrayStack<>();
        int mod;
        while (num!=0){
    
    
            //余数入栈
            //余数可能是0~9也可能是A~F
             mod=num%16;
             if (mod<10){
    
    
                 //数字0到9
                 stack.push((char)(mod+'0'));
             }else {
    
    
                 //否则是数字10到15,要转换成A到F
                 stack.push((char)('A'+mod-10));
             }
             num/=16;

        }
        //按照顺序弹栈
        while (!stack.isEmpty()){
    
    
            Character pop = stack.pop();
            System.out.print(pop);
        }
    }
}

在这里插入图片描述

十六进制转为十进制

在这里插入图片描述

public class HexToDec {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个十六进制的字符串:");
        String num = scanner.nextLine();
        //创建一个栈,存储每一个字符
        ArrayStack<Character> stack = new ArrayStack<>();
        for (int i = 0; i < num.length(); i++) {
    
    
            stack.push(num.charAt(i));
        }
//        System.out.println(stack);
        //依次弹栈并累加计算结果
        int sum = 0;
        //幂数
        int exponent = 0;
        char c;
        while (!stack.isEmpty()) {
    
    
            c = stack.pop();
            sum += Math.pow(16, exponent) * getNumber(c);
            exponent++;
        }
        System.out.println(sum);


    }

    /**
     * 把字符转换为对应的数字
     * 字符是0~9或A~F
     *
     * @param c
     * @return
     */
    private static int getNumber(char c) {
    
    
        if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F')) {
    
    
            throw new IllegalArgumentException("错误的输入十六进制数 " + c);
        }
        //说明字符是符合十六进制的数字要求的
        if (c >= '0' && c <= '9') {
    
    
            return c - '0';
        } else {
    
    
            return 'A' + c - 10;
        }

    }
}

在这里插入图片描述

判断回文

public class JudgeHw {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String str = scanner.nextLine();
        //创建栈
        ArrayStack<Character> stack=new ArrayStack<>();
        char c;
        for (int i = 0; i < str.length(); i++) {
    
    
            //判断字符串的长度是奇数还是偶数
             //如果是奇数的话,则把中间数据过滤掉,不需要压栈
            if (str.length()%2==1&& i==str.length()/2){
    
    
                continue;
            }
            c=str.charAt(i);
            //如果栈空,则入栈
            if (stack.isEmpty()){
    
    
                stack.push(c);
            }else{
    
    
                if (stack.peek()==c){
    
    
                    stack.pop();
                }else {
    
    
                    //不相等则入栈
                    stack.push(c);
                }

            }
            //栈如果非空,则比较栈顶元素和待入栈元素是否相等,如果不相等,则入栈
            //如果相等,则出栈
        }
        //如果最后栈空,则是回文
        if (stack.isEmpty()){
    
    
            System.out.println("是回文");
        }else{
    
    
            System.out.println("不是回文");
        }





    }
}

在这里插入图片描述

有效的括号

在这里插入图片描述
20.有效的括号
思路分析

  • 遇到左括号就入栈
  • 如果遇到右括号
    • 看看栈顶是否有元素 ,如果栈为空,说明无法匹配
    • 如果栈顶有元素,但是括号不匹配,则说明无法匹配
  • 所有字符扫描完毕后,如果栈空,说明有效,否则无效
class Solution {
    
    
    public boolean isValid(String s) {
    
    
  Stack<Character> stack=new Stack<>();
        int len=s.length();
        for (int i = 0; i < len; i++) {
    
    
            char c=s.charAt(i);
            if(c=='('||c=='['||c=='{'){
    
    
                //入栈
                stack.push(c);
            }else{
    
    
                //否则就是右括号
                //如果栈是空的,则无法匹配
                if (stack.isEmpty()) return false;
                //如果栈非空,则出栈进行匹配
                Character pop = stack.pop();
                if (pop=='(' && c!=')') return  false;
                if (pop=='{'&& c!='}') return false;
                if (pop=='['&& c!=']') return false;
            }
        }
        //所有字符扫描完毕后,如果栈空,说明有效,否则无效
        return stack.isEmpty();

    
    }
}

猜你喜欢

转载自blog.csdn.net/qq_52797170/article/details/125701543