美文网首页
栈和队列

栈和队列

作者: freemanIT | 来源:发表于2022-03-17 10:52 被阅读0次

栈是一种特殊的线性表, 只能在一端进行操作

  • 添加元素, push, 入栈
  • 移除元素, pop, 出栈, 移除栈顶
  • 后进先出LIFO 原则

入栈操作

入栈 出栈
    public class Stack<E> {
    
    private List<E> list = new LinkedList<>();
    
   public void clear() {
        list.clear();
    }   
        
        
    public int size() {
        return list.size();
    }
    
    public boolean isEmpty() {
        return list.isEmpty();
    }
    
    public void push(E element) {
        list.add(element);
    }
    
    public E pop() {
        return list.remove(list.size() - 1);
    }
    
    public E top() {
        return list.get(list.size() - 1);
    }
    
}

软件的撤销和恢复功能, 也会用到栈的操作

队列(queue)

队列是一种特殊的线性表, 只能在头尾两端进行操作

队尾: 只能在队尾添加元素, enQueue, 入队

队头: 只能在队头移除元素, deQueue, 出队

先进先出原则, FIFO

队列

接口设计

    public class Queue<E> {
    
    LinkedList<E> list = new LinkedList<>();
    
    public int size() {
        return list.size();
    }
    
    public boolean isEmpty() {
        return list.isEmpty();
    }
    
    public void enQueue(E element) {
        list.add(element);
    }
    
    public E deQueue() {
        return list.remove(0);
    }
    
    public E front() {
        return list.get(0);
    }
    
    public void clear() {
        
    }
    
}

双端队列

能在头尾两端添加删除的队列

    public class Deque<E> {
    LinkedList<E> list = new LinkedList<>();
    
    public int size() {
        return list.size();
    }
    
    public boolean isEmpty() {
        return list.isEmpty();
    }
    
    public void enQueueRear(E element) {
        list.add(element);
    }
    
    public E deQueueRear() {
        return list.remove(list.size() - 1);
    }
    
    public void enQueueFront(E element) {
        list.add(0, element);
    }
    
    public E deQueueFront() {
        return list.remove(0);
    }
    
    public E front() {
        return list.get(0);
    }
    
    public E rear() {
        return list.get(list.size() - 1);
    }
    
    public void clear() {
        
    }
}

循环队列

使用数组实现循环队列以及扩容的实现

    @SuppressWarnings("unchecked")
    public class CircleQueue<E> {
    private int front;
    private int size;
    private E[] elements;
    private static final int DEFAULT_CAPACITY = 10;
    
    public CircleQueue() {
        elements = (E[]) new Object[DEFAULT_CAPACITY];
    }
    
    public int size() {
        return size;
    }
    
    public boolean isEmpty() {
        return size == 0;
    }
    
    public void enQueue(E element) {
        ensureCapacity(size + 1);
        elements[(front + size) % elements.length] = element;
        size++;
    }
    
    public E deQueue() {
        E frontElement = elements[front];
        elements[front] = null;
        front = (front + 1) % elements.length;
        size --;
        return frontElement;
    }
    
    public E front() {
        return elements[front];
    }
    
    public void clear() {
        
    }
    
    private void ensureCapacity(int capacity) {
        int oldCapacity = elements.length;
        if (oldCapacity >= capacity) return;
        
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        E[] newElements = (E[]) new Object[newCapacity];
        for (int i = 0; i < size; i++) {
            newElements[i] = elements[(i + front) % elements.length];
        }
        elements = newElements;
        front = 0;
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("capacity=").append(elements.length).append(" size=").append(size).append(" front=").append(front).append(", [");
        for (int i = 0; i < elements.length; i++) {
            if (i != 0) {
                sb.append(", ");
            }
            sb.append(elements[i]);
        }
        sb.append("]");
        return sb.toString();
    }
}

建议: 尽量避免使用乘*, 除/, 模%, 浮点数运算, 效率比较低

已知n>=0, m>0

n%m, 等价 n - (m > n ? 0 : m), n < 2m

循环双端队列

    @SuppressWarnings("unchecked")
    public class CircleDeque<E> {
    private int front;
    private int size;
    private E[] elements;
    private static final int DEFAULT_CAPACITY = 10;
    
    public CircleDeque() {
        elements = (E[]) new Object[DEFAULT_CAPACITY];
    }
    
    public int size() {
        return size;
    }
    
    public boolean isEmpty() {
        return size == 0;
    }
    
    /**
     * 尾部入队
     * @param element
     */
    public void enQueueRear(E element) {
        ensureCapacity(size + 1);
        elements[index(size)] = element;
        size++;
    }
    
    /**
     * 尾部出队
     * @return
     */
    public E deQueueRear() {
        int rearIndex = index(size - 1);
        E rear = elements[rearIndex];
        elements[rearIndex] = null;
        size--;
        return rear;
    }
    
    /**
     * 头部入队
     * @param element
     */
    public void enQueueFront(E element) {
        ensureCapacity(size + 1);
        front = index(-1);
        elements[front] = element;
        size++;
    }
    
    /**
     * 头部出队
     * @return
     */
    public E deQueueFront() {
        E frontElement = elements[front];
        elements[front] = null;
        front = index(1);
        size--;
        return frontElement;
    }
    
    public E front() {
        return elements[front];
    }
    
    public E rear() {
        return elements[index(size - 1)];
    }
    
    public void clear() {
        for (int i = 0; i < size; i++) {
            elements[index(i)] = null;
        }
        size = 0;
        front = 0;
    }
    
    private void ensureCapacity(int capacity) {
        int oldCapacity = elements.length;
        if (oldCapacity >= capacity) return;
        
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        E[] newElements = (E[]) new Object[newCapacity];
        for (int i = 0; i < size; i++) {
            newElements[i] = elements[index(i)];
        }
        elements = newElements;
        front = 0;
    }
    
    private int index(int index) {
        index += front;
        if (index < 0) {
            return index + elements.length;
        }
        return index - (index >= elements.length ? elements.length : 0);
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("capacity=").append(elements.length).append(" size=").append(size).append(" front=").append(front).append(", [");
        for (int i = 0; i < elements.length; i++) {
            if (i != 0) {
                sb.append(", ");
            }
            sb.append(elements[i]);
        }
        sb.append("]");
        return sb.toString();
    }
}

相关文章

  • 数据结构——栈和队列

    用数组实现栈和队列 用栈实现队列 用队列实现栈 栈和队列的经典算法题最小间距栈宠物收养所 数组实现栈和队列 用数组...

  • 栈和队列

    用栈定义队列(出入栈) 用队列定义栈(数据队列和辅助队列)

  • Algorithm小白入门 -- 队列和栈

    队列和栈队列实现栈、栈实现队列单调栈单调队列运用栈去重 1. 队列实现栈、栈实现队列 队列是一种先进先出的数据结构...

  • 栈和队列

    栈和队列 本质上是稍加限制的线性表 栈和队列定义 栈顺序栈定义 链栈结点定义 队列顺序队列 链队列链队类型定义 链...

  • Python实现栈和队列以及使用list模拟栈和队列

    Python实现栈和队列 Python使用list模拟栈和队列

  • 算法-栈和队列算法总结

    栈和队列算法总结 1 模拟 1.1 使用栈实现队列 1.2 使用队列实现栈 2 栈的应用 2.1 栈操作 2.2 ...

  • 算法分析 [BFS、Greedy贪心] 2019-02-18

    队列 和 栈 232. 用栈实现队列 Implement Queue using Stacks双栈,出队列时,将i...

  • 实 验 四 栈和队列

    一、实验目的与要求:## 1、理解栈和队列抽象数据类型。 2、掌握栈和队列的存储结构和操作实现。 3、理解栈和队列...

  • 栈、队列和链表

    基本数据结构 栈和队列 栈和队列都是动态集合。栈实现的是一种后进先出策略。队列是一种先进先出策略。 栈 栈上的in...

  • 算法导论 基本数据结构

    MIT公开课没有讲到的内容,介绍几种基本数据结构- 栈和队列- 链表- 二叉树 栈和队列 栈和队列都是动态集合,元...

网友评论

      本文标题:栈和队列

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