7. 队列

队列

  1. 队列是一种特殊的线性表,只能在头尾两端操作
  2. 队尾(rear):只能从队尾添加元素,一般叫做入队(enQueue)
  3. 队头(front):只能从队头移除元素,一般叫做出队(deQueue)
  4. 队列内部实现可以使用动态数组或双向链表实现
  5. 优先使用双向链表,因为队列主要往头尾操作元素
  6. 先进先出原则:First In First Out(FIFO)
    队列基本展示

队列的接口设计

  1. public lit size(); //元素数量
  2. public boolean isEmpty(); //是否为空
  3. public void enQueue(E element); //入队 说明:官方API为add()或offer()
  4. public void deQueue(); //出队 说明:官方API为remove()或poll()
  5. public E front(); //获取队列头元素 说明:官方API为peek()

队列的实现

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);
    }
}

双端队列

  1. 双端队列是可以在头尾两端进行添加、删除的队列
    双端队列展示

双端队列接口设计

  1. public lit size(); //元素数量
  2. public boolean isEmpty(); //是否为空
  3. public void enQueueFront(E element); //队头入队
  4. publiv void enQueueRear(E element); //队尾入队
  5. public void deQueueFront(); //队头出队
  6. public void deQueueRear() //队尾出队
  7. public E front(); //获取队列头元素
  8. public E rear(); //获取队尾元素

双端队列的实现

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);
    }
}

循环队列

  1. 循环队列是指用一个队头变量(front)指向数组的第一个变量
    循环队列展示
  2. 每一次出栈,就将front位置的元素取出并删除,然后front+1
  3. 每一次入栈,就根据front和当前元素数量计算出入栈元素的索引,然后将元素放到数组对应的索引位置上

循环队列的接口设计

  1. public lit size(); //元素数量
  2. public boolean isEmpty(); //是否为空
  3. public void enQueue(E element); //入队
  4. public void deQueue(); //出队
  5. public E front(); //获取队列头元素

循环队列的实现

public class CircleQueue<E> {
	private int front;
    private E[] elements;
    prinvate int size;

    private static final int DEFAULT_CAPACITY = 10;
	
	public class CircleQueue() {
		elements = (E []) new Object[]
	}

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void enQueue(E element) {
        ensureCapcity(size + 1);
        elements[index(size)] = element;
        size++;
    }

    public E deQueue() {
        E element = elements[front];
        element[front] = null;
        //更新front
        front = index(1);    (1 + front) % elements.length
        size--;
        return element;
    }

    public E front() {
        return elements[front];
    }

    //保证数组容量
    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;
	}

	private int index(int index) {
		return (index + front) % elements.length;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值