特点
与普通队列不同的是,普通队列是在一端删除(头),另一端添加(尾)
而双端队列是两端都可以删除、添加
双向链表实现双端队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
public class LinkedListDeque<E> implements Deque<E>, Iterable<E> {
@Override public boolean offerFirst(E e) { if (isFull()) { return false; } Node<E> a = sentinel; Node<E> b = sentinel.next; Node<E> added = new Node<>(a, e, b); a.next = added; b.prev = added; size++; return true; }
@Override public boolean offerLast(E e) { if (isFull()) { return false; } Node<E> a = sentinel.prev; Node<E> b = sentinel; Node<E> added = new Node<>(a, e, b); a.next = added; b.prev = added; size++; return true; }
@Override public E pollFirst() { if (isEmpty()) { return null; } Node<E> a = sentinel; Node<E> removed = sentinel.next; Node<E> b = removed.next; a.next = b; b.prev = a; size--; return removed.value; }
@Override public E pollLast() { if (isEmpty()) { return null; } Node<E> b = sentinel; Node<E> removed = sentinel.prev; Node<E> a = removed.prev; a.next = b; b.prev = a; size--; return removed.value; }
@Override public E peekFirst() { if(isEmpty()) { return null; } return sentinel.next.value; }
@Override public E peekLast() { if(isEmpty()) { return null; } return sentinel.prev.value; }
@Override public boolean isEmpty() { return size == 0; }
@Override public boolean isFull() { return size == capacity; }
@Override public Iterator<E> iterator() { return new Iterator<E>() { Node<E> p = sentinel.next;
@Override public boolean hasNext() { return p != sentinel; }
@Override public E next() { E value = p.value; p = p.next; return value; } }; }
static class Node<E> { Node<E> prev; E value; Node<E> next;
public Node(Node<E> prev, E value, Node<E> next) { this.prev = prev; this.value = value; this.next = next; } }
int capacity; int size; Node<E> sentinel = new Node<>(null, null, null);
public LinkedListDeque(int capacity) { this.capacity = capacity; sentinel.next = sentinel; sentinel.prev = sentinel; } }
|
环形数组实现双端队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
public class ArrayDeque1<E> implements Deque<E>, Iterable<E> {
static int inc(int i, int length) { if(i + 1 >= length) { return 0; } return i + 1; }
static int dec(int i, int length) { if(i - 1 < 0) { return length - 1; } return i - 1; }
E[] array; int head; int tail;
@SuppressWarnings("all") public ArrayDeque1(int capacity) { array = (E[]) new Object[capacity + 1]; }
@Override public boolean offerFirst(E e) { if(isFull()) { return false; } head = dec(head, array.length); array[head] = e; return true; }
@Override public boolean offerLast(E e) { if(isFull()) { return false; } array[head] = e; tail = inc(tail, array.length); return true; }
@Override public E pollFirst() { if(isEmpty()) { return null; } E e = array[head]; array[head] = null; head = inc(head, array.length); return e; }
@Override public E pollLast() { if(isEmpty()) { return null; } tail = dec(tail, array.length); E e = array[tail]; array[tail] = null; return e; }
@Override public E peekFirst() { if(isEmpty()) { return null; } return array[head]; }
@Override public E peekLast() { if(isEmpty()) { return null; } return array[dec(tail, array.length)]; }
@Override public boolean isEmpty() { return head == tail; }
@Override public boolean isFull() { if(tail > head) { return tail - head == array.length - 1; } else if(tail < head) { return head - tail == 1; } else { return false; } }
@Override public Iterator<E> iterator() { return new Iterator<E>() { int p = head; @Override public boolean hasNext() { return p != tail; }
@Override public E next() { E e = array[p]; p = inc(p, array.length); return e; } }; } }
|
练习:二叉树s字层序遍历
基本思想和普通遍历一致,但是s型遍历需要用双端队列,奇数列在尾部添加,偶数列在头部添加
这样就可以实现s型遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
public List<List<Integer>> zigzagLevelOrder(TreeNode root) { List<List<Integer>> result = new ArrayList<>(); if(root == null) { return result; } LinkedListQueue<TreeNode> queue = new LinkedListQueue<>(); queue.offer(root); int c1 = 1; boolean odd = true; while(!queue.isEmpty()) { LinkedList<Integer> level = new LinkedList<>(); int c2 = 0; for (int i = 0; i < c1; i++) { TreeNode n = queue.pool();
if(odd) { level.offerLast(n.val); } else { level.offerFirst(n.val); }
if(n.left != null) { queue.offer(n.left); c2++; } if(n.right != null) { queue.offer(n.right); c2++; } } odd = !odd; result.add(level); c1 = c2; } return result; }
|