Designing the ArrayDeque
We use the same representation idea as ArrayQueue: a backing array, a front index, and a size field.
private T[] arr;
private int front;
private int size;
The item i positions after the first end is at:
(front + i) % arr.length
From this formula, we get the positions we need:
- The first item is at
front. - The last item is at
(front + size - 1) % arr.length. - The next free slot after the last item is at
(front + size) % arr.length.
For addLast, we use the next free slot after the last item, exactly like ArrayQueue uses its computed back slot.
For addFirst, we need the slot before front, wrapping around to the end of the array if front is 0. Be careful in Java: (front - 1) % arr.length is negative when front is 0, because Java’s % is a remainder operator, not a mathematical modulo operator. Use this instead:
(front + arr.length - 1) % arr.length
Empty and Full
As with ArrayQueue, the size field is what lets us tell an empty deque from a full one.
Here is a wrapped deque in a capacity-5 array:
addLast writes here
↓
┌───┬───┬───┬───┬───┐
│ 4 │ 6 │ _ │ _ │ 2 │
└───┴───┴───┴───┴───┘
↑ ↑
last front
The deque contents are 2, 4, 6. Here front is 4 and size is 3. The last item is at (4 + 3 - 1) % 5 = 1. The slot for addFirst is (4 + 5 - 1) % 5 = 3.
Growing the Array
When the array is full, we grow it exactly as ArrayQueue does: copy the items in deque order into a larger array and reset front to 0.
Operations and Complexity
isEmpty(), getFirst(), removeFirst(), and addLast(T item): These work as isEmpty, front, dequeue, and enqueue do in ArrayQueue. Each is , and addLast is amortized .
getLast(): Return the item at the last item’s index. This is .
removeLast(): Clear the slot at the last item’s index and decrement size. front does not move. This is .
addFirst(T item): Move front back one slot and write the item there, growing the array first when it is full. This is amortized .