队列
别看这个,没用,还是多刷力扣队列题
定义
队列是以顺序的方式维护一组数据的集合,在一端添加数据,从另一端移除数据。一般来讲,添加的一端称之尾,而移除一端称为头 。
队列接口定义
// 队列的接口定义
public interface Queue<E> {
// 向队尾添加元素
// 添加成功,返回true; 添加失败返回 false
boolean offer(E value);
// 获取头部元素,并移除元素
E poll();
// 获取头部元素,不移除
E peek();
// 判断队列是否为空
boolean isEmpty();
// 判断队列是否满
boolean isFull();
}
实现队列
链表实现
使用单向循环带哨兵链表实现队列
public class LinkedListQueue<E> implements Queue<E>, Iteable<E> {
private static class Node<E> {
E value;
Node next;
public Node(E value, Node<E> next) {
this.value = value;
this.next = next;
}
}
Node<E> head = new Node(null, null); // 哨兵头
Node<E> tail = head; // 哨兵尾
private int size;
private int capacity;
public LinkedListQueue(int capacity) {
this.capacity = capacity;
tail.next = head;
}
public LinkedListQueue() {
tail.next = head;
}
@Override
public boolean offer(E value) {
if (isFull()) {
return false;
}
Node<E> added = new Node<>(value, head);
tail.next = added;
tail = add;
size++;
return true;
}
@Ovrride
public E poll() {
if (isEmpty()) {
return null;
}
Node<E> first = head.next;
head.next = first.next;
if (first == tail) {
tail = head;
}
size--;
return first.value;
}
@Override
pulic E peek() {
if (isEmpty()) {
return null;
}
return head.next.value;
}
@Override
public boolean isEmpty() {
return head == tail;
}
@Override
public boolean isFull() {
return size == capacity;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
Node<E> p = head.next;
@Override
public boolean hasNext() {
return p != head;
}
@Override
public E next() {
E value = p.value;
p = p.next;
return value;
}
}
}
}
环形数组实现
方法一
public class ArrayQueue<E> implements Queue<E>, Iterable<E> {
private E[] array;
private int head = 0;
private int tail = 0;
public ArrayQueue(int capacity) {
array = (E[]) new Object[capacity + 1];
}
// 添加元素
@Override
public boolean offer(E value) {
// 判断队列是否满
if (isFull()) {
return false;
}
array[tail] = value;
tail = (tail + 1) % array.length;
return true;
}
// 移除队列头部元素,并返回
@Override
public E poll() {
if (isEmpty()) {
return null;
}
E value = array[head];
head = (head + 1) % array.length;
return value;
}
// 获取队列头部元素
@Override
public E peek() {
if(isEmpty()) {
return null;
}
return array[head];
}
@Override
public boolean isEmpty() {
return head == tail;
}
@Override
public boolean isFull() {
return (tail + 1) % array.length == head;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
int p = head;
@Override
public boolean hasNext() {
return p != null;
// return (p + 1) $ array.length != head; 是对的吗?
}
@Override
public E next() {
E value = array[p];
p = (p + 1) % array.length;
return value;
}
}
}
}
方法二 – 修改方法一
添加size变量判断队列是否为空或者为满的情况
public class ArrayQueue2<E> implements Queue<E>, Iterable<E> {
private E[] array;
private int head = 0;
private int tail = 0;
private int size = 0;
public ArrayQueue2(int capacity) {
array = (E[]) new Object[capacity + 1];
}
// 添加元素
@Override
public boolean offer(E value) {
// 判断队列是否满
if (isFull()) {
return false;
}
array[tail] = value;
tail = (tail + 1) % array.length;
size++;
return true;
}
// 移除队列头部元素,并返回
@Override
public E poll() {
if (isEmpty()) {
return null;
}
E value = array[head];
head = (head + 1) % array.length;
size--;
return value;
}
// 获取队列头部元素
@Override
public E peek() {
if(isEmpty()) {
return null;
}
return array[head];
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public boolean isFull() {
return size = array.length;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
int p = head;
int count = 0;
@Override
public boolean hasNext() {
return count < size;
}
@Override
public E next() {
E value = array[p];
p = (p + 1) % array.length;
count++;
return value;
}
}
}
}
方法三
public class ArrayQueue3<E> implements Queue<E>, Iterable<E> {
private final E[] array;
private int head = 0;
private int tail = 0;
public ArrayQueue(int capacity) {
array = (E[]) new Object[capacity];
}
// 添加元素
@Override
public boolean offer(E value) {
// 判断队列是否满
if (isFull()) {
return false;
}
array[tail & array.length] = value;
tail = tail + 1;
return true;
}
// 移除队列头部元素,并返回
@Override
public E poll() {
if (isEmpty()) {
return null;
}
E value = array[head % array.length];
head = head + 1;
return value;
}
// 获取队列头部元素
@Override
public E peek() {
if(isEmpty()) {
return null;
}
return array[head % array.length];
}
@Override
public boolean isEmpty() {
return head == tail;
}
@Override
public boolean isFull() {
return tail - head == array.length;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
int p = head;
@Override
public boolean hasNext() {
return p != tail;
}
@Override
public E next() {
E value = array[p % array.length];
p++;
return value;
}
}
}
}
改进算法,防止数组越界
- 前提是数组容量必须是2的n次方
public class ArrayQueue3<E> implements Queue<E>, Iterable<E> {
private final E[] array;
private int head = 0;
private int tail = 0;
public ArrayQueue(int capacity) {
array = (E[]) new Object[capacity];
}
// 添加元素
@Override
public boolean offer(E value) {
// 判断队列是否满
if (isFull()) {
return false;
}
array[tail & array.length - 1] = value;
tail = tail + 1;
return true;
}
// 移除队列头部元素,并返回
@Override
public E poll() {
if (isEmpty()) {
return null;
}
E value = array[head % array.length - 1];
head = head + 1;
return value;
}
// 获取队列头部元素
@Override
public E peek() {
if(isEmpty()) {
return null;
}
return array[head % array.length - 1];
}
@Override
public boolean isEmpty() {
return head == tail;
}
@Override
public boolean isFull() {
return tail - head == array.length;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
int p = head;
@Override
public boolean hasNext() {
return p != tail;
}
@Override
public E next() {
E value = array[p % array.length - 1];
p++;
return value;
}
}
}
}
二叉树层序遍历
使用队列
public class Leetcode102{
public static void main(String[] args) {
TreeNode root = new TreeNode(
new TreeNode(new TreeNode(4),
2,
new TreeNode(5)),
1,
new TreeNode(new TreeNode(6),
3,
new TreeNode(7)));
LinkedListQueue<TreeNode> queue = new LinkedListQueue<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode n = queue.poll();
System.out.println(n);
if (n.left != null) {
queue.offer(n.left);
}
if (n.right != null) {
queue.offer(n.right);
}
}
}
}
在此基础上实现分层效果
public class Leetcode102{
public static void main(String[] args) {
TreeNode root = new TreeNode(
new TreeNode(new TreeNode(4),
2,
new TreeNode(5)),
1,
new TreeNode(new TreeNode(6),
3,
new TreeNode(7)));
LinkedListQueue<TreeNode> queue = new LinkedListQueue<>();
queue.offer(root);
int c1 = 1;
while (!queue.isEmpty()) {
int c2 = 0;
for(int i = 0; i < c1; i++) {
TreeNode n = queue.poll();
System.out.print(n + " ");
if (n.left != null) {
queue.offer(n.left);
c2++;
}
if (n.right != null) {
queue.offer(n.right);
c2++;
}
}
System.out.println();
c1 = c2;
}
}
}
力扣102题的实现
public class Leetcode102{
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) {
return res;
}
LinkedList<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int c1 = 1;
while (!queue.isEmpty()) {
int c2 = 0;
List<Integer> list = new ArrayList<>();
for(int i = 0; i < c1; i++) {
TreeNode n = queue.poll();
list.add(n.val);
if (n.left != null) {
queue.offer(n.left);
c2++;
}
if (n.right != null) {
queue.offer(n.right);
c2++;
}
}
res.add(list);
c1 = c2;
}
return res;
}
}
List<Integer> list = new ArrayList<>();
for(int i = 0; i < c1; i++) {
TreeNode n = queue.poll();
list.add(n.val);
if (n.left != null) {
queue.offer(n.left);
c2++;
}
if (n.right != null) {
queue.offer(n.right);
c2++;
}
}
res.add(list);
c1 = c2;
}
return res;
}
}