棧和隊列

一.棧(Stack)前端

*棧也是一種線性表結構java

*相比數組,棧對應的操做是數組的子集後端

*棧的元素從一端進、同一端出,且爲後進先出,Last In First Out(LIFO數組

 

1.棧的應用:app

——各類編輯器中無處不在的undo(撤銷)操做編輯器

——程序調用的系統棧ide

2.棧的基本實現:函數

先建立一個接口Stack<E>:oop

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

 

建立類ArrayStack<E>實現接口,實現棧的基本功能:ui

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\n", 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);
                }
            }
        }
}
相關文章
相關標籤/搜索