内容来自刘宇波老师算法与数据结构体系课
1、循环队列
| 上次基于动态数组实现的队列,出队是 O(n) 级别的,性能不高,这里用另外一种思路来实现队列 |
| |
| 使用两个变量 front 和 tail,分别代表数组第一个元素的索引和最后一个元素的后一个索引 |
| 使用 data[front] 出队,data[tail] 入队 |
| 队列为空:size == 0 |
| 队列为满:size == length |
| |
| |
| |
| |
| |
| |
| public class LoopQueue<E> implements Queue<E> { |
| |
| private E[] data; |
| private int front; |
| private int tail; |
| private int size; |
| |
| public LoopQueue(int capacity) { |
| data = (E[]) new Object[capacity]; |
| front = tail = size = 0; |
| } |
| |
| public LoopQueue() { |
| this(10); |
| } |
| |
| @Override |
| public void enqueue(E e) { |
| if (size == data.length) resize(data.length * 2); |
| |
| data[tail] = e; |
| tail = (tail + 1) % data.length; |
| size++; |
| } |
| |
| @Override |
| public E dequeue() { |
| if (isEmpty()) throw new RuntimeException("队列为空"); |
| |
| E ret = data[front]; |
| data[front] = null; |
| front = (front + 1) % data.length; |
| size--; |
| |
| if (size == data.length / 4 && data.length / 2 != 0) resize(data.length / 2); |
| return ret; |
| } |
| |
| @Override |
| public E getFront() { |
| if (isEmpty()) throw new RuntimeException("队列为空"); |
| return data[front]; |
| } |
| |
| @Override |
| public int getSize() { |
| return size; |
| } |
| |
| @Override |
| public boolean isEmpty() { |
| return size == 0; |
| } |
| |
| public int getCapacity() { |
| return data.length; |
| } |
| |
| |
| |
| |
| private void resize(int newCapacity) { |
| E[] newData = (E[]) new Object[newCapacity]; |
| for (int i = 0; i < size; i++) { |
| newData[i] = data[(i + front) % data.length]; |
| } |
| data = newData; |
| front = 0; |
| tail = size; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| sb.append(String.format("LoopQueue2: size = %d, capacity = %d\n", size, getCapacity())); |
| sb.append("Front ["); |
| for (int i = 0; i < size; i++) { |
| sb.append(data[(i + front) % data.length]); |
| if (i != size - 1) sb.append(", "); |
| } |
| sb.append("] Tail"); |
| return sb.toString(); |
| } |
| } |
2、双端队列
| |
| |
| |
| |
| |
| |
| public class Deque<E> { |
| |
| private E[] data; |
| private int front; |
| private int tail; |
| private int size; |
| |
| public Deque(int capacity) { |
| data = (E[]) new Object[capacity]; |
| front = tail = size = 0; |
| } |
| |
| public Deque() { |
| this(10); |
| } |
| |
| public void addFront(E e) { |
| if (size == data.length) resize(data.length * 2); |
| |
| front = (front != 0) ? (front - 1) : (data.length - 1); |
| data[front] = e; |
| size++; |
| } |
| |
| public void addLast(E e) { |
| if (size == data.length) resize(data.length * 2); |
| |
| data[tail] = e; |
| tail = (tail + 1) % data.length; |
| size++; |
| } |
| |
| public E removeFront() { |
| if (isEmpty()) throw new RuntimeException("队列为空"); |
| |
| E ret = data[front]; |
| data[front] = null; |
| front = (front + 1) % data.length; |
| size--; |
| |
| if (size == data.length / 4 && data.length / 2 != 0) resize(data.length / 2); |
| return ret; |
| } |
| |
| public E removeLast() { |
| if (isEmpty()) throw new RuntimeException("队列为空"); |
| |
| tail = (tail != 0) ? (tail - 1) : (data.length - 1); |
| E ret = data[tail]; |
| data[tail] = null; |
| size--; |
| |
| if (size == data.length / 4 && data.length / 2 != 0) resize(data.length / 2); |
| return ret; |
| } |
| |
| public E getFront() { |
| if (isEmpty()) throw new RuntimeException("队列为空"); |
| return data[front]; |
| } |
| |
| public E getLast() { |
| if (isEmpty()) throw new RuntimeException("队列为空"); |
| return (tail != 0) ? data[tail - 1] : data[data.length - 1]; |
| } |
| |
| public boolean isEmpty() { |
| return size == 0; |
| } |
| |
| public int getSize() { |
| return size; |
| } |
| |
| public int getCapacity() { |
| return data.length; |
| } |
| |
| private void resize(int newCapacity) { |
| E[] newData = (E[]) new Object[newCapacity]; |
| for (int i = 0; i < size; i++) { |
| newData[i] = data[(i + front) % data.length]; |
| } |
| data = newData; |
| front = 0; |
| tail = size; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| sb.append(String.format("Deque: size = %d, capacity = %d\n", getSize(), getCapacity())); |
| sb.append('['); |
| for (int i = 0; i < getSize(); i++) { |
| sb.append(data[(i + front) % data.length]); |
| if (i != getSize() - 1) sb.append(", "); |
| } |
| sb.append(']'); |
| return sb.toString(); |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步