1οΈβ£ Deque(λ±, Double Ended Queue)
Deque(λ±, Double Ended Queue)λ μμͺ½ λμμ μ½μ κ³Ό μμ λ₯Ό ν μ μλ μλ£ κ΅¬μ‘°μ λλ€.
Javaμμλ java.util
ν¨ν€μ§μμ μ 곡νλ Deque
μΈν°νμ΄μ€μ μ΄λ₯Ό ꡬνν ν΄λμ€μΈ ArrayDeque
μ LinkedList
λ₯Ό ν΅ν΄ μ¬μ©ν μ μμ΅λλ€.
Deque
λ ν(Queue)μ μ€ν(Stack)μ κΈ°λ₯μ λͺ¨λ ν¬ν¨νκ³ μμ΅λλ€.
1οΈβ£ λ°ν¬ κΈ°λ³Έ ꡬ쑰
-
λ°ν¬μ κΈ°λ³Έ ꡬ쑰λ μλ°©ν₯μμ μ½μ μμ κ°λ₯ν ꡬ쑰
-
μΌλΆ κΈ°λ₯μ μ ννμ¬ μ©λμ λ§κ² λ³ν κ°λ₯
-
add
λremove
κ³μ΄μ μμΈλ₯Ό λ°μμν΅λλ€.- λλ¬Έμ μμΈ μ²λ¦¬κ° κ°λ₯ν©λλ€.
-
offer
μ΄λpoll
κ³μ΄μnull
μ΄λfalse
λ₯Ό λ°νν©λλ€.- λλ¬Έμ
return
κ° (λ°νκ°)μ λ°μμ μ²λ¦¬ν μ μμ΅λλ€.
- λλ¬Έμ
2οΈβ£ Dequeμ μ£Όμ λ©μλ.
1οΈβ£ μ½μ μ°μ°.
-
addFirst(E e)
: μ§μ λ μμλ₯Ό λ±μ μμͺ½μ μΆκ°ν©λλ€. -
addLast(E e)
: μ§μ λ μμλ₯Ό λ±μ λ€μͺ½μ μΆκ°ν©λλ€. -
offerFirst(E e)
: μ§μ λ μμλ₯Ό λ±μ μμͺ½μ μΆκ°ν©λλ€. -
offerLast(E e)
: μ§μ λ μμλ₯Ό λ±μ λ€μͺ½μ μΆκ°ν©λλ€.
2οΈβ£ μμ μ°μ°.
-
removeFirst()
: λ±μ μμͺ½μμ μμλ₯Ό μ κ±°νκ³ λ°νν©λλ€. -
removeLast()
: λ±μ λ€μͺ½μμ μμλ₯Ό μ κ±°νκ³ λ°νν©λλ€. -
pollFirst()
: λ±μ μμͺ½μμ μμλ₯Ό μ κ±°νκ³ λ°νν©λλ€. -
pollLast()
: λ±μ λ€μͺ½μμ μμλ₯Ό μ κ±°νκ³ λ°νν©λλ€.
3οΈβ£ μ‘°ν μ°μ°.
-
getFirst()
: λ±μ μμͺ½μ μλ μμλ₯Ό λ°νν©λλ€. -
getLast()
: λ±μ λ€μͺ½μ μλ μμλ₯Ό λ°νν©λλ€. -
peekFirst()
: λ±μ μμͺ½μ μλ μμλ₯Ό λ°νν©λλ€. -
peekLast()
: λ±μ λ€μͺ½μ μλ μμλ₯Ό λ°νν©λλ€.
4οΈβ£ κΈ°ν μ°μ°.
-
size()
: λ±μ μλ μμμ μλ₯Ό λ°νν©λλ€. -
isEmpty()
: λ±μ΄ λΉμ΄ μλμ§ μ¬λΆλ₯Ό νμΈν©λλ€.
3οΈβ£ μκ° λ³΅μ‘λ.
Deque
μΈν°νμ΄μ€μ μκ° λ³΅μ‘λλ μ΄λ₯Ό ꡬνν ν΄λμ€μ λ°λΌ λ¬λΌμ§λλ€.
Javaμμλ μ£Όλ‘ ArrayDeque
μ LinkedList
λ₯Ό μ¬μ©νμ¬ Deque
λ₯Ό ꡬνν©λλ€.
1οΈβ£ ArrayDeque
- μ½μ κ³Ό μμ μ°μ° (μκ³Ό λ€ λͺ¨λ): νκ· μ μΌλ‘ O(1)
- μ‘°ν μ°μ° (μκ³Ό λ€ λͺ¨λ): O(1)
-
ArrayDeque
λ λ°°μ΄μ κΈ°λ°μΌλ‘ ꡬνλκΈ° λλ¬Έμ, λ°°μ΄μ΄ κ½ μ°¨λ©΄ μλμΌλ‘ ν¬κΈ°λ₯Ό λ리μ§λ§, μ΄ κ³Όμ μ amortized O(1)λ‘ κ°μ£Όλ©λλ€.
2οΈβ£ LinkedList
- μ½μ κ³Ό μμ μ°μ° (μκ³Ό λ€ λͺ¨λ): O(1)
- μ‘°ν μ°μ° (μκ³Ό λ€ λͺ¨λ): O(1)
-
LinkedList
λ μ΄μ€ μ°κ²° 리μ€νΈλ‘ ꡬνλμ΄ μμ΄ κ° λ Έλκ° μ΄μ κ³Ό λ€μ λ Έλμ λν μ°Έμ‘°λ₯Ό κ°μ§κ³ μμ΅λλ€.
LinkedListλ κ° λ
Έλκ° μ΄μ λ
Έλμ λ€μ λ
Έλμ μ°Έμ‘°λ₯Ό κ°μ§κ³ μμ΄ μ½μ
κ³Ό μμ κ° O(1)μ μκ° λ³΅μ‘λλ₯Ό κ°μ§λλ€.
νμ§λ§ νμμλ O(n)μ μκ°μ΄ μμλ©λλ€.
ArrayDequeλ λ°°μ΄μ μ¬μ©νμ¬ λ΄λΆμ μΌλ‘ ꡬνλκΈ° λλ¬Έμ μ½μ
κ³Ό μμ μμλ νκ· μ μΌλ‘ O(1)μ μκ° λ³΅μ‘λλ₯Ό κ°μ§λ©°,
νΉν νμ λμμμ μ°μ°μ΄ λΉ λ¦
λλ€.
λ€λ§, λ΄λΆμ μΌλ‘ λ°°μ΄μ΄ κ°λ μ°¨λ©΄ ν¬κΈ°λ₯Ό μ‘°μ ν΄μΌ νλ―λ‘ μ΅μ μ κ²½μ° O(n)μ μκ° λ³΅μ‘λκ° λ°μν μ μμ΅λλ€.
Deque λ λ€μν μν©μμ μ μ°νκ² μ¬μ©λ μ μλ μ μ©ν μλ£κ΅¬μ‘°μ λλ€.
νΉν μμͺ½ λμμμ λΉ λ₯Έ μ½μ κ³Ό μμ κ° νμν κ²½μ° μ μ©ν©λλ€.
3οΈβ£ μ§μ Deque μΈν°νμ΄μ€ ꡬν.
κ°λ¨ν λ°°μ΄μ μ¬μ©νμ¬ Deque
λ₯Ό ꡬνν΄λ³΄κ² μ΅λλ€.
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SimpleArrayDeque<E> {
private static final int DEFALT_CAPACITY = 10;
private E[] elements;
private int head;
private int tail;
private int size;
public SimpleArrayDeque() {
elements = (E[]) new Object[DEFALT_CAPACITY];
head = 0;
tail = 0;
size = 0;
}
public void addFirst(E e) {
if (size == elements.length) {
resize();
}
head = (head - 1 + elements.length) % elements.length;
elements[head] = e;
size++;
}
public void addLast(E e) {
if (size == elements.length) {
resize();
}
elements[tail] = e;
tail = (tail + 1) % elements.length;
size++;
}
public E removeFirst() {
if (size == 0) {
throw new NoSuchElementException();
}
E element = elements[head];
elements[head] = null; // for garbege collection
head = (head + 1);
size--;
return element;
}
public E removeLast() {
if (size == 0) {
throw new NoSuchElementException();
}
tail = (tail - 1 + elements.length) % elements.length;
E element = elements[tail];
elements[tail] = null; // for garbage collection
size--;
return element;
}
public E getFirst() {
if (size == 0) {
throw new NoSuchElementException();
}
return elements[head];
}
public E getLast() {
if (size == 0) {
throw new NoSuchElementException();
}
return elements[(tail - 1 + elements.length) % elements.length];
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
private void resize() {
int newCapacity = elements.length * 2;
E[] newElements = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i] = elements[(head + i) % elements.length];
}
elements = newElements;
head = 0;
tail = size;
}
public ArrayList<E> toArrayList() {
return IntStream.range(0, size)
.mapToObj(i -> elements[(head + i) % elements.length])
.collect(Collectors.toCollection(ArrayList::new));
}
}
// Main
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
SimpleArrayDeque<Integer> deque = new SimpleArrayDeque<>();
deque.addFirst(1);
deque.addLast(2);
deque.addFirst(0);
deque.addLast(3);
ArrayList<Integer> dequeList = deque.toArrayList();
System.out.println("=== dequeList === ");
System.out.println(dequeList);
System.out.println("First element: " + deque.getFirst());
System.out.println("Last element: " + deque.getLast());
System.out.println("=== dequeList === ");
dequeList = deque.toArrayList();
System.out.println(dequeList);
System.out.println("Removed first element: " + deque.removeFirst());
System.out.println("Remove last element: " + deque.removeLast());
System.out.println("=== dequeList === ");
dequeList = deque.toArrayList();
System.out.println(dequeList);
System.out.println("Deque size: " + deque.size());
System.out.println("Is deque empty? " + deque.isEmpty());
System.out.println("=== dequeList === ");
dequeList = deque.toArrayList();
System.out.println(dequeList);
}
}
/*
=== μΆλ ₯ ===
=== dequeList ===
[0, 1, 2, 3]
First element: 0
Last element: 3
=== dequeList ===
[0, 1, 2, 3]
Removed first element: 0
Remove last element: 3
=== dequeList ===
[1, 2]
Deque size: 2
Is deque empty? false
=== dequeList ===
[1, 2]
*/
4οΈβ£ μ λ ₯ μ ν Deque(Input-Restricted Deque).
μ λ ₯ μ ν Deque(Input-Restricted Deque)μ λ±μ νμͺ½ λμμλ§ μ½μ μ΄ κ°λ₯νκ³ , μμͺ½ λμμ μμ κ° κ°λ₯ν μλ£κ΅¬μ‘°μ λλ€.
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class InputRestrictedDeque<E> {
private static final int DEFAULT_CAPACITY = 10;
private E[] elements;
private int head;
private int tail;
private int size;
@SuppressWarnings("unchecked")
public InputRestrictedDeque() {
elements = (E[]) new Object[DEFAULT_CAPACITY];
head = 0;
tail = 0;
size = 0;
}
public void addLast(E e) {
if (size == elements.length) {
resize();
}
elements[tail] = e;
tail = (tail + 1) % elements.length;
size++;
}
public E removeFirst() {
if (size == 0) {
throw new NoSuchElementException();
}
E element = elements[head];
elements[head] = null; // for garbage collection
head = (head + 1) % elements.length;
size--;
return element;
}
public E removeLast() {
if (size == 0) {
throw new NoSuchElementException();
}
tail = (tail - 1 + elements.length) % elements.length;
E element = elements[tail];
elements[tail] = null; // for gatbage collection
size--;
return element;
}
public E getFirst() {
if (size == 0) {
throw new NoSuchElementException();
}
return elements[head];
}
public E getLast() {
if (size == 0) {
throw new NoSuchElementException();
}
return elements[(tail - 1 + elements.length) % elements.length];
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
private void resize() {
int newCapacity = elements.length * 2;
@SuppressWarnings("unchecked")
E[] newElements = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i] = elements[(head + i) % elements.length];
}
elements = newElements;
head = 0;
tail = size;
}
public ArrayList<E> toArrayList() {
return IntStream.range(0, size)
.mapToObj(i -> elements[(head + i) % elements.length])
.collect(Collectors.toCollection(ArrayList::new));
}
}
// Main
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
InputRestrictedDeque<Integer> deque = new InputRestrictedDeque<>();
deque.addLast(1);
deque.addLast(2);
deque.addLast(3);
ArrayList<Integer> dequeList = deque.toArrayList();
System.out.println("=== dequeList ===");
System.out.println(dequeList);
System.out.println("First element: " + deque.getFirst());
System.out.println("Last element: " + deque.getLast());
System.out.println("=== dequeList ===");
dequeList = deque.toArrayList();
System.out.println(dequeList);
System.out.println("Remove first element: " + deque.removeFirst());
System.out.println("Remove last elment: " + deque.removeLast());
System.out.println("=== dequeList ===");
dequeList = deque.toArrayList();
System.out.println(dequeList);
System.out.println("Deque size: " + deque.size());
System.out.println("Is deque empty? " + deque.isEmpty());
}
}
/*
=== μΆλ ₯ ===
=== dequeList ===
[1, 2, 3]
First element: 1
Last element: 3
=== dequeList ===
[1, 2, 3]
Remove first element: 1
Remove last elment: 3
=== dequeList ===
[2]
Deque size: 1
Is deque empty? false
*/
1οΈβ£ μ½λ μ€λͺ .
-
λ°°μ΄ μ΄κΈ°ν :
DEFAULT_CAPACITY
ν¬κΈ°μ λ°°μ΄μ μ΄κΈ°ννκ³ ,head
,tail
,size
λ³μλ₯Ό μ΄κΈ°νν©λλ€. -
μ½μ μ°μ°(
addLast
) : μμλ₯Ό λ±μ λ§μ§λ§ μ μΆκ°ν©λλ€. λ°°μ΄μ΄ κ°λ μ°¨λ©΄ ν¬κΈ°λ₯Ό λ λ°°λ‘ λ립λλ€. -
μμ μ°μ°(
removeFirst
,removeLaste
) : 첫 λ²μ§Έ μμμ λ§μ§λ§ μμλ₯Ό κ°κ° μ κ±°ν©λλ€. -
μ‘°ν μ°μ°(
getFirst
,getLast
) : 첫 λ²μ§Έ μμμ λ§μ§λ§ μμλ₯Ό λ°νν©λλ€. -
κΈ°ν λ©μλ :
size
μisEmpty
λ©μλλ λ±μ ν¬κΈ°μ λ±μ΄ λΉμ΄ μλμ§ μ¬λΆλ₯Ό λ°νν©λλ€. -
λ°°μ΄ ν¬κΈ° μ‘°μ (
resize
) : λ°°μ΄μ΄ κ°λ μ°° λ νΈμΆλλ©°, λ°°μ΄μ ν¬κΈ°λ₯Ό λ λ°°λ‘ λλ¦¬κ³ μμλ₯Ό μ λ°°μ΄λ‘ 볡μ¬ν©λλ€.
μ΄ μμ μμλ μμλ₯Ό λ±μ λμλ§ μ½μ ν μ μλ μ λ ₯ μ ν λ±μ ꡬννμ΅λλ€.
νμμ λ°λΌ μ΄ κ΅¬νμ νμ₯νκ±°λ μμ νμ¬ μꡬμ¬νμ λ§κ² μ¬μ©ν μ μμ΅λλ€.
5οΈβ£ μΆλ ₯ μ ν Deque(Output-Restricted Deque).
μΆλ ₯ μ ν Deque(Output-Restricted Deque)μ μμͺ½ λμμ μ½μ μ΄ κ°λ₯νμ§λ§, νμͺ½ λμμλ§ μμ κ° κ°λ₯ν μλ£ κ΅¬μ‘°μ λλ€.
μ΄ κ΅¬μ‘°λ μμͺ½ λμμ μμλ₯Ό μΆκ°ν μ μμ§λ§, μμ λ νμͺ½ λμμλ§ ν μ μμ΅λλ€.
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class OutputRestrictedDeque<E> {
private static final int DEFAULT_CAPACITY = 10;
private E[] elements;
private int head;
private int tail;
private int size;
@SuppressWarnings("unchecked")
public OutputRestrictedDeque() {
elements = (E[]) new Object[DEFAULT_CAPACITY];
head = 0;
tail = 0;
size = 0;
}
public void addFirst(E e) {
if (size == elements.length) {
resize();
}
head = (head - 1 + elements.length) % elements.length;
elements[head] = e;
size++;
}
public void addLast(E e) {
if (size == elements.length) {
resize();
}
elements[tail] = e;
tail = (tail + 1) % elements.length;
size++;
}
public E removeFirst() {
if (size == 0) {
throw new NoSuchElementException();
}
E element = elements[head];;
elements[head] = null; // for garbage collection
head = (head + 1) % elements.length;
size--;
return element;
}
public E getFirst() {
if (size == 0) {
throw new NoSuchElementException();
}
return elements[head];
}
public E getLast() {
if (size == 0) {
throw new NoSuchElementException();
}
return elements[(tail - 1 + elements.length) % elements.length];
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
private void resize() {
int newCapacity = elements.length * 2;
@SuppressWarnings("unchecked")
E[] newElements = (E[]) new Object[newCapacity];
for (int i = 0; i < size; i++) {
newElements[i] = elements[(head + 1) % elements.length];
}
elements = newElements;
head = 0;
tail = size;
}
public ArrayList<E> toArrayList() {
return IntStream.range(0, size)
.mapToObj(i -> elements[(head + i) % elements.length])
.collect(Collectors.toCollection(ArrayList::new));
}
}
// Main
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
OutputRestrictedDeque<Integer> deque = new OutputRestrictedDeque<>();
deque.addFirst(1);
deque.addLast(2);
deque.addFirst(0);
deque.addLast(3);
ArrayList<Integer> dequeList = deque.toArrayList();
System.out.println("=== dequeList === ");
System.out.println(dequeList);
System.out.println("First element: " + deque.getFirst());
System.out.println("Last element: " + deque.getLast());
System.out.println("=== dequeList === ");
dequeList = deque.toArrayList();
System.out.println(dequeList);
System.out.println("Remove first element: " + deque.removeFirst());
System.out.println("=== dequeList === ");
dequeList = deque.toArrayList();
System.out.println(dequeList);
System.out.println("Deque size: " + deque.size());
System.out.println("Is deque empty? " + deque.isEmpty());
System.out.println("=== dequeList === ");
dequeList = deque.toArrayList();
System.out.println(dequeList);
}
}
/*
=== μΆλ ₯ ===
=== dequeList ===
[0, 1, 2, 3]
First element: 0
Last element: 3
=== dequeList ===
[0, 1, 2, 3]
Remove first element: 0
=== dequeList ===
[1, 2, 3]
Deque size: 3
Is deque empty? false
=== dequeList ===
[1, 2, 3]
*/
1οΈβ£ μ½λ μ€λͺ .
-
λ°°μ΄ μ΄κΈ°ν :
DEFAULT_CAPACITY
ν¬κΈ°μ λ°°μ΄μ μ΄κΈ°ννκ³ ,head
,tail
,size
λ³μλ₯Ό μ΄κΈ°ν ν©λλ€. -
μ½μ μ°μ°(
addFirst
,addLast
) : μμλ₯Ό λ±μ 첫 λ²μ§Έ λλ λ§μ§λ§μ μΆκ°ν©λλ€. λ°°μ΄μ΄ κ°λ μ°¨λ©΄ ν¬κΈ°λ₯Ό λ λ°°λ‘ λ립λλ€. -
μμ μ°μ°(
removeFirst
) : 첫 λ²μ§Έ μμλ₯Ό μ κ±°ν©λλ€. μΆλ ₯ μ ν λ±μμλ 첫 λ²μ§Έ μμλ§ μ κ±°ν μ μμ΅λλ€. -
μ‘°ν μ°μ°(
getFirst
,getLast
) : 첫 λ²μ§Έ μμμ λ§μ§λ§ μμλ₯Ό λ°νν©λλ€. -
κΈ°ν λ©μλ :
size
μisEmpty
λ©μλλ λ±μ ν¬κΈ°μ λ±μ΄ λΉμ΄ μλμ§ μ¬λΆλ₯Ό λ°νν©λλ€. -
λ°°μ΄ ν¬κΈ° μ‘°μ (
resize
) : λ°°μ΄μ΄ κ°λ μ°° λ νΈμΆλλ©°, λ°°μ΄μ ν¬κΈ°λ₯Ό λ λ°°λ‘ λλ¦¬κ³ μμλ₯Ό μ λ°°μ΄λ‘ 볡μ¬ν©λλ€.
μ΄ μμ μμλ μμλ₯Ό λ±μ μμͺ½ λμμ μ½μ ν μ μκ³ , 첫 λ²μ§Έ μμλ§ μ κ±°ν μ μλ μΆλ ₯ μ ν λ±μ ꡬννμ΅λλ€.
νμμ λ°λΌ μ΄ κ΅¬νμ νμ₯νκ±°λ μμ νμ¬ μꡬμ¬νμ λ§κ² μ¬μ©ν μ μμ΅λλ€.