zoukankan      html  css  js  c++  java
  • 06-java实现队列

    06-java实现队列

    本人git https://github.com/bigeyes-debug/Algorithm

    一丶队列

    • 队列是特殊的线性结构,只能在头尾两端操作
    • 队尾入队,队头出队,
    • FIFO
    • 队列可以用动态数组和双向链表实现
    • 优先使用双向链表,主要在头尾进行操作

    二丶队列的接口设计(和之前的线性结构类似)

    public class Queue<E> {
        // 使用双向链表实现队列
        private List<E> list = new LinkedList<>();
        // 元素的数量
        public int size();
        // 是否为空
        public boolean isEmpty();
        // 入队
        public void enQueue(E element);
        // 出队
        public E deQueue();
        // 获取队列的头元素
        public E front();
    }
    
    

    三丶队列的实现

    public class Queue<E> {
        private List<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 class Deque<E> {
        private List<E> list = new LinkedList<>();
    	
        // 元素的数量
        public int size() {
            return list.size();
        }
        // 是否为空
        public boolean isEmpty() {
            return list.isEmpty();
        }
        // 从队头出队
        public E deQueueFront() {
            return list.remove(0);
        }
        // 从队头入队
        public void enQueueFront(E element) {
            list.add(0, element);
        }
        // 从队尾入队
        public void enQueueRear(E element) {
            list.add(element);
        }
        // 从队尾出队
        public E deQueueRear() {
            return list.remove(list.size() - 1);
        }
        // 获取队列的头元素
        public E front() {
            return list.get(0);
        }
        // 获取队列的尾元素
        public E rear() {
            return list.get(list.size() - 1);
        }
    }
    
    

    六丶循环队列

    • 队列内部实现也可以用动态数组实现,并且将各项接口优化到O(1)的时间复杂度, 这个用数组实现并优化之后的队列就叫做: 循环队列。

    七、循环队列的接口设计

    public class CircleQueue<E> {
        // 记录第0个元素的索引
        private int front;
        // 当前队列存储的元素个数
        private int size;
        // 用来存储元素的数组
        private E[] elements;
        // 当前队列存储的元素数量
        public int size();
        // 当前队列是否为空
        public boolean isEmpty();
        // 入队
        public void enQueue(E element);
        // 出队
        public E deQueue();
        // 查看索引为0的元素
        public E front();
    }
    

    八丶循环队列的实现

    3.1 构造方法

    public class ArrayList<E> {
        private E[] elements;
        // 设置elements数组默认的初始化空间
        private static final int DEFAULT_CAPACITY = 10;
    	
        public CircleQueue() {
            elements = (E[]) new Object[DEFAULT_CAPACITY];
        }
    }
    
    

    3.2 入队

    • 入队前需要考虑两个问题:队列是否需要扩容和计算入队实际索引。

    3.2.1 动态扩容

    动态数组的扩容方法拿来直接用即可

    private void ensureCapacity(int capacity) {
        int oldCapacity = elements.length;
        if (oldCapacity >= capacity) return;
    		
        // 新容量为旧容量的1.5倍
        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
        front = 0;
    }
    
    

    3.2.2 索引计算

    • 获取实际索引公式 (front+index)%elements.length;
         private int index(int index) {
              return (front +index)%elements.length;
         }
    
    

    入队代码

    public void enQueue(E element) {
        // 数组扩容判断
        ensureCapacity(size + 1);
        // 索引计算,并赋值
        elements[index(size)] = element;
        // size加一
        size++;
    }
    
    

    3.3 出队

    • 一定要更新front指针,一定不要忘
    public E deQueue() {
        // 获取出队元素
        E frontElement = elements[front];
        // 将索引位置致空
        elements[front] = null;
        // 更新font
        front = index(1);
        // size减一
        size--;
        // 返回出队元素
        return frontElement;
    }
    
    
  • 相关阅读:
    业务领域建模Domain Modeling
    用例建模Use Case Modeling
    分析一套源代码的代码规范和风格并讨论如何改进优化代码
    结合工程实践选题调研分析同类软件产品
    如何提高程序员的键盘使用效率
    python知识准备及环境配置
    一张图片在Python操作下的4种玩法(附源码)
    Python中的错误和异常
    当你忘记网站上的密码时怎么办?Python如何快速帮你找回?
    Python最简单的图片爬虫,20行代码带你爬遍整个网站
  • 原文地址:https://www.cnblogs.com/bianzhuo/p/13500523.html
Copyright © 2011-2022 走看看