数据结构-栈(通过数组和单向链表实现)

Array Stack& Single Linked List Stack

概述

  1. 栈是一个先入后出(FILO, First In Last Out)的有序列表
  2. 栈的出/入操作限制只能在线性表的同一个端进行

应用场景

  1. 子程序的调用: 在跳往子程序前, 会先将下一个指令的地址存到栈中, 直到子程序执行完后再将地址取出, 回到原来的位置 如浏览器的后退/向前, JVM的虚拟机栈
  2. 表达式的转换(如 中缀表达式转后缀表达式)与求值
  3. 二叉树的遍历
  4. 图形的深度优先(depth-first)搜索法

通过数组实现


/** 定义数组栈*/
class ArrayStack {
    /** 栈大小*/
    private int maxSize;
    /** 通过该数组存放数据, 模拟栈数据结构*/
    private int[] stack;
    /** 栈顶的 index, 初始值为-1*/
    private int top = -1;

    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        stack = new int[maxSize];
    }

    /** 栈满*/
    public boolean isFull() {
        return top == maxSize - 1;
    }

    /** 栈空*/
    public boolean isEmpty() {
        return top == -1;
    }

    /** 入/压栈*/
    public void push(int value) {
        if (isFull()) {
            System.out.println("入栈失败, 栈已满!");
            return;
        }
        top++;
        stack[top] = value;
    }

    /** 出/弹栈*/
    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("出栈失败, 没有数据!");
        }
        int value = stack[top];
        top--;
        return value;
    }

    /** 从栈顶开始打印所有内容*/
    public void list() {
        if (isEmpty()) {
            System.out.println("打印失败, 没有数据!");
            return;
        }
        for (int i = top; i >= 0; i--) {
            System.out.printf("stack[%d]=%d\n", i, stack[i]);
        }
    }
}

public class ArrayStackApp {
    public static void main(String[] args) {
        System.out.println("push(添加数据到栈顶)");
        System.out.println("pop(从栈取数据)");
        System.out.println("show(打印栈所有内容)");
        System.out.println("exit(退出程序)");
        /** 创建数组栈实例*/
        ArrayStack stack = new ArrayStack(3);
        String command;
        boolean loop = true;
        Scanner scanner = new Scanner(System.in);
        while (loop) {
            System.out.println("请输入命令!");
            command = scanner.next();
            switch (command) {
                case "show":
                    stack.list();
                    break;
                case "push":
                    System.out.println("请输入数值!");
                    int value = scanner.nextInt();
                    stack.push(value);
                    break;
                case "pop":
                    try {
                        int result = stack.pop();
                        System.out.printf("数据 %d已出栈!\n", result);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case "exit":
                    scanner.close();
                    loop = false;
                    break;
                default:
                    break;
            }
        }

        System.out.println("程序结束!");
    }

}

通过单向链表实现


/** 定义节点*/
class Node {
    int no;
    Node next;

    /** 创建一个新的节点, 同时 next指向, 之前的栈顶节点*/
    public Node(int no, Node next){
        this.no = no;
        this.next = next;
    }

    public int getNo() {
        return no;
    }
}

/** 定义不带头的单向链表栈*/
class ListStack {
    /** 栈大小*/
    int size;
    /** 栈内有效节点个数*/
    int count;
    /** 栈顶节点*/
    Node currentNode;

    public ListStack(int size) {
        this.size = size;
        this.count = 0;
        this.currentNode = null;
    }

    /** 栈满*/
    public boolean isFull() {
        return count == size ? true: false;
    }

    /** 栈空*/
    public boolean isEmpty() {
        return count == 0 ? true: false;
    }

    /** 入/压栈*/
    public void push(int value) {
        if (isFull()) {
            System.out.println("入栈失败, 栈已满!");
            return;
        }
        /** 新建节点, 再将它设为栈顶节点, 此节点的 next是引用了, 之前的栈顶节点*/
        currentNode = new Node(value, currentNode);
        /** 递增有效节点个数*/
        count++;
    }

    /** 出/弹栈*/
    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("出栈失败, 没有数据!");
        }
        int no = currentNode.getNo();
        /** 将当前下一个节点覆盖当前节点*/
        currentNode = currentNode.next;
        /** 递减有效节点个数*/
        count--;
        return no;
    }

    /** 打印栈顶的节点内容*/
    public void peak(){
        if (isEmpty()) {
            System.out.println("打印失败, 没有数据!");
            return;
        }
        System.out.println(currentNode.getNo());
    }

    /** 打印栈的所有节点内容*/
    public void show(){
        if (isEmpty()) {
            System.out.println("打印失败, 没有数据!");
            return;
        }

        Node temp = currentNode;
        int i = count;
        while (true) {
            if (temp == null) {
                return;
            }
            System.out.printf("stack[%d]=%d\n", i, temp.getNo());
            i--;
            temp = temp.next;
        }
    }
}

public class SingleLinkedListStackApp {
    public static void main(String[] args) {
        System.out.println("push(添加数据到栈顶)");
        System.out.println("pop(从栈取数据)");
        System.out.println("peak(打印栈顶的节点内容)");
        System.out.println("show(打印栈的所有节点内容)");
        System.out.println("exit(退出程序)");
        /** 创建链表栈实例*/
        ListStack stack = new ListStack(3);
        String command;
        boolean loop = true;
        Scanner scanner = new Scanner(System.in);
        while (loop) {
            System.out.println("请输入命令!");
            command = scanner.next();
            switch (command) {
                case "push":
                    System.out.println("请输入数值!");
                    int value = scanner.nextInt();
                    stack.push(value);
                    break;
                case "pop":
                    try {
                        int result = stack.pop();
                        System.out.printf("数据 %d已出栈!\n", result);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case "peak":
                    stack.peak();
                    break;
                case "show":
                    stack.show();
                    break;
                case "exit":
                    scanner.close();
                    loop = false;
                    break;
                default:
                    break;
            }
        }

        System.out.println("程序结束!");
    }

}

如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!

猜你喜欢

转载自blog.csdn.net/qcl108/article/details/109036155