Summary

Deque ADT

  • both LIFO and FIFO

Circular array implementation - arrays

OperationMethodPerformance
enqueue(v)add before head/after tail-
dequeue()remove from head/tail-
peek()get head/tail-

DLL implementation

OperationMethodPerformance
enqueue(v)add before head/after tail-
dequeue()remove from head/tail-
peek()get head/tail-
a1a2...anheadtailinoutinout

java.util.Dequeue interface

Library implemetations

java
import java.util.ArrayDeque;
import java.util.LinkedList;

Deque<Integer> A = new ArrayDeque<>();
// or
Deque<Integer> A = new LinkedList<>();
// insert at tail, following java.util.Queue
A.add(5);
A.add(10);
A.add(15);
A.add(25); // A = 5 -> 10 -> 15 -> 25

// insertHead
A.addFirst(4); // 4 -> 5 -> 10 -> 15 -> 25
// think of it as first element to be popped

// insertTail
A.addLast(8); // 4 -> 5 -> 10 -> 15 -> 25 -> 8

// remove at head, following java.util.Queue
int a = A.remove(); // 5 -> 10 -> 15 -> 25 -> 8

// removeHead
int b = A.removeFirst(); // 10 -> 15 -> 25 -> 8

// removeTail
int c = A.removeLast(); // 10 -> 15 -> 25

// peek at head, following java.util.Queue
int d = A.peek(); // 10

// peekHead
int e = A.peekFirst(); // 10

// peekTail
int f = A.peekLast(); // 25

Concept

Dequeue operations

  • enqueue(v)
    • add v to the front/back of the deque
  • dequeue()
    • get the first/last item in the deque and remove it
  • peek()
    • get the first/last item in the deque without removing it
4321inoutinout

Deque as Queue

Queue MethodDeque Method
add(v)addLast(v) or add(v)
remove()removeFirst() or remove()
peek()peekFirst() or peek()

Deque as Stack

Stack MethodDeque Method
push(v)addFirst(v)
pop()removeFirst() or remove()
peek()peekFirst() or peek()

by convention following queue ADT, the back(last) of the dequeue is the tail, the front(first) refers to the head

Application

Kattis: backspace

  • stack behaviour for backspace
  • queue behaviour for printing
java
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(System.out);

Deque<Character> dq = new ArrayDeque<>();

for (char c : br.readLine().toCharArray())
	if (c == '<') // we need LIFO
		dq.removeFirst();
	else
		dq.addFirst(c);

while (!dq.isEmpty())
	pw.append(dq.removeLast()); // we need FIFO

pw.println();
pw.close();

Kattis: integerlist

  • reversible queue
java
ArrayDeque<Integer> dq = new ArrayDeque<>();

for (int j = 0; j < n; j++)
	dq.add(Integer.parseInt(numArr[j])); // add normally

boolean reversed = false;
for (char c : prog.toCharArray()) {
	if (c == 'R') {
		reversed = !reversed;
	} else {
		if (!dq.isEmpty()) {
			if (reversed) { // take from head or tail depending on reversed state
				dq.pollLast();
			} else {
				dq.pollFirst();
			}
		}
	}
}

StringJoiner sj = new StringJoiner(",", "[", "]");
while (!dq.isEmpty()) {
	int next = 0;
	if (reversed) {
		next = dq.pollLast();
	} else {
		next = dq.pollFirst();
	}
	sj.add(String.format("%d", next));
}
pw.println(sj.toString());

pw.close();

use StringJoiner to handle the joining of strings separated by a delimter