3.栈和队列

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 {
    //使用单链表实现,节点类
    private class Node{
        private Node next;
        private T t;
        public Node() {};
        public Node(Node next, T t) {
            this.next = next;
            this.t = t;
        }
    }
    private Node 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(top,t);
        size++;
        return true;
    }
    public T pop() {
        if(size == 0) {
            System.out.println("栈为空");
            return null;
        }else {
            //出栈并删除栈中该元素
            Node 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 {
    private class Node {
        private Node next;
        private T t;
        public Node() {
        }
        public Node(Node next, T t) {
            this.next = next;
            this.t = t;
        }   
    }
    private Node front;
    private Node 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(null,t);
            back = front;
        }
        Node newNode = new Node(null,t);
        back.next = newNode;
        back = newNode;
        currentSize++;
        return true;
    }
    public T dequeue() {
        if(currentSize == 0) {
            System.out.println("队列为空");
            return null;
        }
        Node node = front;
        front = front.next;
        node.next = null;
        currentSize--;
        return node.t;
        
    }
}

2.2队列的应用

排队论,例如卖票窗口

你可能感兴趣的:(3.栈和队列)