美文网首页
3.栈和队列

3.栈和队列

作者: a9f9e33f60c3 | 来源:发表于2019-03-18 11:55 被阅读0次

    1.栈

    只能在一个位置上进行插入和删除的表,又称为LIFO(后进先出)表。

    1.1栈的实现

    任何实现表的方法都能实现栈,ArrayList和LinkedList均能实现栈。常用的两种实现栈的方法是:数组和链式结构

    1.1.1栈的数组实现

    1.用数组实现栈,存放数据
    2.简单的push和pop方法实现
    3.栈顶指针topOfStack以及栈的容量maxSize

    public class MyStackByArray {
        private Object [] theArray = null;//用数组存储
        private int topOfStack = -1;//栈顶指针
        private int maxSize = 0;//栈的容量
        
        public MyStackByArray() {
            this(10);//初始容量为10
        }
        public MyStackByArray(int initialSize) {
            if(initialSize > 0) {
                this.maxSize = initialSize;
                theArray = new Object [maxSize];
            }else {
                System.out.println("栈容量不能小于等于0");
            }
            
        }
        //压栈
        public boolean push(Object o) {
            //考虑栈溢出
            if(topOfStack == maxSize - 1) {
                System.out.println("栈溢出");
                return false;
            }
            else{
                theArray[++topOfStack] = o;
                return true;
            }
        }
        //出栈
        public Object pop() {
            if(topOfStack == -1) {
                System.out.println("空栈");
                return null;
            }else {
                return theArray[topOfStack--];
            }   
        }
        
    }
    

    1.1.2栈的链表实现

    1.节点类的定义
    2.栈顶元素top
    3.当前栈中元素size
    4.pop和push方法的简单实现

    public class MyStackByLink <T>{
        //使用单链表实现,节点类
        private class Node<T>{
            private Node<T> next;
            private T t;
            public Node() {};
            public Node(Node<T> next, T t) {
                this.next = next;
                this.t = t;
            }
        }
        private Node<T> top;//栈顶元素
        private int size = 0;//当前栈的大小
        public MyStackByLink() {
            top = null;
        }
        public int length() {
            return size;
        }
        public boolean push(T t) {
            //让top指向新创建的元素,并将该元素的next指向原来的top
            top = new Node<T>(top,t);
            size++;
            return true;
        }
        public T pop() {
            if(size == 0) {
                System.out.println("栈为空");
                return null;
            }else {
                //出栈并删除栈中该元素
                Node<T> node = top;
                top = top.next;
                node.next = null;
                size--;
                return node.t;
            }
        }
    

    1.2栈的应用

    1.后缀表达式的计算
    正常的数学表达式称为中缀表达式,例如a+bc+(de+f)*g;
    a b c * + d e * f + g * + 则称为后缀表达式,又称为后缀或逆波兰记法。
    计算方法:见到一个数就把他压入栈中,在遇到一个运算符时,该运算符就作用于从该栈中弹出的两个数上,再将所得结果压入栈中。
    2.中缀到后缀的转换
    当读到一个操作数的时候,立即把它放到输出中。操作符不立即输出,而是压入栈中。
    压栈规则:
    1)从栈中弹出栈元素直到发现优先级更低的元素为止,此操作完成后再压入栈中
    2)左圆括号的优先级最高,除非处理右圆括号,否则不会从栈中弹出,左圆括号只弹出并不输出
    3)读到输入末尾,将栈元素弹出直至变成空栈

    2.队列

    末端插入,首段删除,是一个FIFO(先进先出)表

    2.1队列的实现

    2.1.1队列的数组实现

    1.队头front与队尾back
    2.enqueue和dequeue的简单实现
    3.当前队列中元素个数currentSize和队列容量maxSize
    4.循环数组

    public class MyQueueByArray {
        private Object theArray [];//使用数组实现
        private int front;//队头
        private int back;//队尾
        private int currentSize;//当前队列元素个数
        private int maxSize;//队列最大元素个数
        public MyQueueByArray() {};
        public MyQueueByArray(int maxSize) {
            this.maxSize = maxSize;
            theArray = new Object [maxSize];
            front = 0;
            back = 0;
            currentSize = 0;
        }
        public boolean enqueue(Object o) {
            if(currentSize == maxSize) {
                System.out.println("队列已满");
                return false;
            }
            theArray[back] = o;
            back = (back+1) % maxSize;
            currentSize++;
            return true;
        }
        public Object dequeue() {
            if(currentSize == 0) {
                System.out.println("队列为空");
                return null;
            }
            Object obj = theArray[front];
            front = (front+1) % maxSize;
            currentSize--;
            return obj;
        }
    

    2.1.2队列的链表实现

    1.节点类
    2.enqueue和dequeue的简单实现

    public class MyQueueByLink<T> {
        private class Node<T> {
            private Node<T> next;
            private T t;
            public Node() {
            }
            public Node(Node<T> next, T t) {
                this.next = next;
                this.t = t;
            }   
        }
        private Node<T> front;
        private Node<T> back;
        private int maxSize;
        private int currentSize;
        
        public MyQueueByLink(int maxSize) {
            front = null;
            back = null;
            this.maxSize = maxSize;
            currentSize = 0;
        }
    
        public boolean enqueue(T t) {
            if(maxSize == currentSize) {
                System.out.println("队列已满");
                return false;
            }else if(currentSize == 0) {
                front = new Node<T>(null,t);
                back = front;
            }
            Node<T> newNode = new Node<T>(null,t);
            back.next = newNode;
            back = newNode;
            currentSize++;
            return true;
        }
        public T dequeue() {
            if(currentSize == 0) {
                System.out.println("队列为空");
                return null;
            }
            Node<T> node = front;
            front = front.next;
            node.next = null;
            currentSize--;
            return node.t;
            
        }
    }
    

    2.2队列的应用

    排队论,例如卖票窗口

    相关文章

      网友评论

          本文标题:3.栈和队列

          本文链接:https://www.haomeiwen.com/subject/exkvmqtx.html