旧街凉风 提交于 2019-12-31 09:51:03

栈(FILO)

栈的介绍

1)  栈的英文为(stack)

2)  栈是一个先入后出(FILO-FirstInLastOut)的有序列表。

3)  栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的

一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。

4)  根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元

素最先删除,最先放入的元素最后删除。

栈的应用场景

1)  子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以 回到原来的程序中。

2)  处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆 栈中。

3)  表达式的转换[中缀表达式转后缀表达式]与求值(实际解决)。

4)  二叉树的遍历。

5)  图形的深度优先(depth一first)搜索法。 

栈的代码实现

1.数组(推荐)

2.单链表

package com.stack;

import java.util.Scanner;

/**
 * @program: DataStructures
 * @description: 栈
 * @author: XuDeming
 * @date: 2019-12-30 17:00:11
 **/
public class StackDemo {
    public static void main(String[] args) {

        System.out.println("***栈测试***");

        Scanner scanner = new Scanner(System.in);
        System.out.println("请选择队列种类");
        System.out.println("1:数组栈");
        System.out.println("2:链表栈");
        int kind = scanner.nextInt();

        // 创建栈
        System.out.println("请输入栈长度:");
        int size = scanner.nextInt();
        Stack stack = kind == 1 ? new ArrayStack(size) : new LinkedStack(size);

        boolean flag = true;

        // 队列操作菜单
        while (flag) {
            System.out.println("***队列操作菜单***");
            System.out.println("0: 退出程序");
            System.out.println("1: 打印栈元素");
            System.out.println("2: 显示栈内元素个数");
            System.out.println("3: 入栈");
            System.out.println("4: 出栈");
            System.out.println("5:查看栈顶元素");
            System.out.println("6: 清空栈");

            // 接收一个字符
            int i = scanner.nextInt();
            switch (i) {
                case 1:
                    stack.show();
                    break;
                case 2:
                    System.out.println("栈内元素个数为:" + stack.length());
                    break;
                case 3:
                    System.out.println("请输入一个数字");
                    int a = scanner.nextInt();
                    stack.push(a);
                    break;
                case 4:
                    try {
                        System.out.println("从栈中取出的元素为:" + stack.pop());
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 5:
                    try {
                        System.out.println("栈顶元素为:" + stack.peek());
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 6:
                    stack.clean();
                    break;
                case 0:
                    flag = false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序退出~");

    }

}

interface Stack {

    void push(int value);
    int pop();
    int peek();
    void show();
    int length();
    void clean();

}

class ArrayStack implements Stack{

    private int size;// 栈的长度
    private int[] stack;// 栈的实现 数组
    private int top = -1;// 指向栈顶的指针

    // 构造器
    public ArrayStack(int size) {
        this.size = size;
        this.stack = new int[this.size];
    }

    // 栈满
    private boolean isFull() {
        return top + 1 == size;
    }
    // 栈空
    private boolean isEmpty() {
        return top == -1;
    }
    // 入栈
    @Override
    public void push(int value) {
        if (isFull()) {
            System.out.println("栈满");
            return;
        }
        stack[++top] = value;
    }
    // 出栈
    @Override
    public int pop() {
        if (isEmpty()) throw new RuntimeException("栈空");
        return stack[top--];
    }

    // 查看栈顶元素
    public int peek() {
        if (isEmpty()) throw new RuntimeException("栈空");
        return stack[top];
    }

    // 打印栈
    @Override
    public void show() {
        if (isEmpty()) {
            System.out.println("栈空");
            return;
        }
        int temp = top;
        while (temp != -1) {
            System.out.print(stack[temp--] + "\t");
        }
        System.out.println();
    }

    // 返回栈内元素个数
    @Override
    public int length() {
        return top + 1;
    }

    // 清空栈
    @Override
    public void clean() {
        top = -1;
    }
}

class Node {

    int value;
    Node next;

    public Node(int value) {
        this.value = value;
    }

}

class LinkedStack implements Stack {

    Node head;
    int length;
    public LinkedStack (int size) {
        length = size;
        head = new Node(0);
    }

    private boolean isFull() {
        return length == length();
    }

    private boolean isEmpty() {
        return length() == 0;
    }

    @Override
    public void push(int value) {
        if (isFull()) {
            System.out.println("栈满");
            return;
        }
        if (getTopNode() == null) {
            head.next = new Node(value);
        } else {
            getTopNode().next = new Node(value);
        }
    }

    @Override
    public int pop() {
        if (length() == 0) throw new RuntimeException("栈空");
        Node temp = head.next;
        while (temp.next.next != null) {
            temp = temp.next;
        }
        Node last = temp.next;
        temp.next = null;
        return last.value;
    }

    @Override
    public int peek() {
        Node temp = getTopNode();
        if (temp == null) throw new RuntimeException("栈空");
        return temp.value;
    }

    private Node getTopNode() {
        if (isEmpty()) return null;
        Node temp = head.next;
        while (temp.next != null) {
            temp = temp.next;
        }
        return temp;
    }

    @Override
    public void show() {
        if (isEmpty()) {
            System.out.println("栈空");
            return;
        }
        LinkedStack newStack = new LinkedStack(length);
        Node temp = head.next;
        // 头插法(插在第一个节点位置上)
        while (temp != null) {
            // 找到新链表的头指针
            Node node = newStack.head;
            // 准备插入的节点
            Node node1 = new Node(temp.value);
            // 是否有节点 插入方式不同
            if (!newStack.isEmpty())  {
                node1.next = node.next;
            }
            node.next = node1;
            temp = temp.next;
        }
        // 遍历新链表
        Node node = newStack.head.next;
        while (node != null) {
            System.out.print(node.value + "\t");
            node = node.next;
        }
        System.out.println();
    }

    @Override
    public int length() {
        if (head.next == null) return 0;
        int size = 0;
        Node temp = head.next;
        while (temp != null) {
            size++;
            temp = temp.next;
        }
        return size;
    }

    @Override
    public void clean() {
        head.next = null;
    }
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!