栈和队列

Posted m-chen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了栈和队列相关的知识,希望对你有一定的参考价值。

一.栈(Stack)

*栈也是一种线性表结构

*相比数组,栈对应的操作是数组的子集

*栈的元素从一端进、同一端出,且为后进先出,Last In First Out(LIFO

 

1.栈的应用:

——各种编辑器中无处不在的undo(撤销)操作

——程序调用的系统栈

2.栈的基本实现:

先创建一个接口Stack<E>:

public interface Stack<E> {
    int getSize(); //栈的大小
    boolean isEmpty(); //判断栈是否为空
    void push(E e); //入栈
    E pop(); //出栈
    E peek(); //查看栈顶元素
}

 

创建类ArrayStack<E>实现接口,实现栈的基本功能:

public class ArrayStack<E> implements Stack<E>{
    private Array<E> array;
    
    //有参构造函数
    public ArrayStack(int capacity) {
        array = new Array<E>(capacity);
    }
    //无参构造函数
    public ArrayStack() {
        array = new Array<E>();
    }
    
    @Override
    public int getSize() {
        return array.getSize();
    }

    @Override
    public boolean isEmpty() {
        return array.isEmpty();
    }

    @Override
    public void push(E e) {
        array.addLast(e);
    }

    @Override
    public E pop() {
        return array.removeLast();
    }

    @Override
    public E peek() {
        return array.getLast();
    }
    
    public int getCapacity(){
        return array.getCapacity();
    }
    
    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        res.append("Stack: ");
        res.append(‘[‘);
        for(int i = 0 ; i < array.getSize() ; i ++){
            res.append(array.getArr(i));
            if(i != array.getSize() - 1)
                res.append(", ");
        }
        res.append("] top");
        return res.toString();
    }
    
}

 

用栈的原理解决刮花是否正确的成对出现的问题:

import java.util.Stack;

class Solution {
    public boolean isValid(String s){
        Stack<Character> stack = new Stack<>();
        for(int i=0; i<s.length(); i++){
            char c = s.charAt(i);
            if(c==‘(‘ || c==‘[‘ || c==‘{‘){
                stack.push(c);
            }else {
                if(stack.isEmpty()){
                    return false;
                }
                
                char topChar = stack.pop();
                if(topChar==‘(‘ && c!=‘)‘)
                    return false;
                if(topChar==‘[‘ && c!=‘]‘)
                    return false;
                if(topChar==‘{‘ && c!=‘}‘)
                    return false;
            }
        }
        return stack.isEmpty();
    }
    

    public static void main(String[] args) {

        System.out.println((new Solution()).isValid("()[]{}"));
        System.out.println((new Solution()).isValid("([)]"));
        System.out.println((new Solution()).isValid("{[]}"));
    }
}

 

二.队列(Queue)

1.什么是队列?

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。即First In First Out (FIFO)。

2.实现数组队列:

public class ArrayQueue<E> implements Queue<E> {
    
    private Array<E> queue;
    
    public ArrayQueue(int capacity) {
        queue = new Array<E>(capacity);
    }

    public ArrayQueue() {
        queue = new Array<E>();
    }
    
    @Override
    public int getSize() {
        return queue.getSize();
    }

    @Override
    public boolean isEmpty() {
        return queue.isEmpty();
    }

    @Override
    public void enqueue(E e) {
        queue.addLast(e);
    }

    @Override
    public E dequeue() {
        return queue.removeFirst();
    }

    @Override
    public E getFront() {
        return queue.getFirst();
    }
    
    public int getCapacity(){
        return queue.getCapacity();
    }
    
    @Override
    public String toString(){
        StringBuilder ret = new StringBuilder();
        ret.append("Queue: ");
        ret.append("front [");
        for(int i=0; i<queue.getSize(); i++){
            ret.append(queue.getArr(i));
            if(i != queue.getSize()-1)
                ret.append(",");
        }
        ret.append("] tail");
        return ret.toString();
    }

    public static void main(String[] args) {
        ArrayQueue<Integer> queue = new ArrayQueue<>();
        for(int i=0; i<10; i++){
            queue.enqueue(i);
            if(i % 3 ==0)
                queue.dequeue();
            System.out.println(queue);
        }
    }
}

 

3.实现循环队列:

public class LoopQueue<E> implements Queue<E> {
    private E[] arr;
    private int front;
    private int tail;
    private int size;
    
    public LoopQueue(int capacity) {
        arr = (E[])new Object[capacity+1];
        front = 0;
        tail = 0;
        size = 0;
    }
    
    public LoopQueue() {
        this(10);
    }
    
    @Override
    public int getSize() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return tail==front;
    }

    @Override
    public void enqueue(E e) {
        if((tail + 1) % arr.length == front)
            resize(getCapacity()*2);
        arr[tail] = e;
        tail = (tail + 1) % arr.length;
        size++;
    }

    @Override
    public E dequeue() {
         if(isEmpty())
             throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
         E ret = arr[front];
         arr[front] = null;
         front = (front + 1) % arr.length;
         size--;
         if(size == getCapacity() / 4 && getCapacity() / 2 != 0)
                resize(getCapacity() / 2);
         return ret;
    }

    @Override
    public E getFront() {
        // TODO Auto-generated method stub
        return null;
    }
    
    public int getCapacity(){
        return arr.length - 1;
    }
    
    public void resize(int newCapacity){
        E[] newArr = (E[])new Object[newCapacity + 1];
        for(int i=0; i<size; i++){
            newArr[i] = arr[(i+front)%arr.length];
        }
        arr = newArr;
        front = 0;
        tail = size;
    }
    
     @Override
        public String toString(){

            StringBuilder res = new StringBuilder();
            res.append(String.format("Queue: size = %d , capacity = %d
", size, getCapacity()));
            res.append("front [");
            for(int i = front ; i != tail ; i = (i + 1) % arr.length){
                res.append(arr[i]);
                if((i + 1) % arr.length != tail)
                    res.append(", ");
            }
            res.append("] tail");
            return res.toString();
        }
     
     public static void main(String[] args){

            LoopQueue<Integer> queue = new LoopQueue<>();
            for(int i = 0 ; i < 10 ; i ++){
                queue.enqueue(i);
                System.out.println(queue);

                if(i % 3 == 2){
                    queue.dequeue();
                    System.out.println(queue);
                }
            }
        }
}

 

 

 

 

以上是关于栈和队列的主要内容,如果未能解决你的问题,请参考以下文章

栈和队列基本操作

栈和队列

博客作业03--栈和队列

博客作业03--栈和队列

栈和队列知识点总结

栈和队列的面试题Java实现