
Queue
큐는 FIFO(First In First Out)형태를 가진 자료구조이다. 후입선출 구조인 stack과 반대라고 생각하면 된다.
Enqueue : 큐 뒤에 데이터를 추가
Dequeue : 큐 앞쪽의 데이터를 삭제
Java의 Queue interface
stack은 클래스로 구현해서 제공하지만 큐는 Queue 인터페이스만 있고 별도의 클래스가 없다.
따라서 Queue 인터페이스를 구현한 클래스를 사용해야한다.
https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html
Queue (Java Platform SE 8 )
A collection designed for holding elements prior to processing. Besides basic Collection operations, queues provide additional insertion, extraction, and inspection operations. Each of these methods exists in two forms: one throws an exception if the opera
docs.oracle.com
자바 공식 도큐먼트에 큐를 구현한 클래스들이 나와있다. 이중에서 가장 많이 사용해본건 LinkedList와 ArrayDeque, PriorityQueue
Queue의 method
public interface Queue<E> extends Collection<E> {
boolean add(E e);
boolean offer(E e);
E remove();
E poll();
E element();
E peek();
}
Queue의 인터페이스를 살펴보면 위와 같다.
- 데이터 입력
- add와 offer는 둘다 데이터를 삽입하는 메서드이다.
- interface의 주석에 따르면 offer는 용량이 제한된 큐에 사용되고 add보다 권장된다고 한다.
- offer()는 큐가 꽉 차 있을때 추가를 시도하면 false가 반환된다.
- add()는 큐가 꽉 차 있을대 IllegalStateException이 발생된다.
- 데이터 삭제
- remove와 poll은 데이터를 삭제하는 메서드이다.
- remove의 경우 큐가 비어있으면 NoSuchElementException이 발생하고 poll은 큐가 비어있다면 null을 반환한다.
- 데이터 열람
- element와 peek은 데이터를 반환하지만 삭제하지는 않는다.
- element의 경우 remove와 같이 큐가 비어있다면 NoSuchElementException 이 발생되고 peek은 큐가 비었다면 null을 반환한다.
직접 구현해보기
리스트로 큐를 구현해보았다. 먼저 큐의 인터페이스를 생성해주었다.
public interface GyungminQueue<E> {
boolean queueIsEmpty();
boolean queueIsFull();
int size();
void enqueue(E value);
E peek();
E dequeue();
}
queueIsEmpty() : 큐가 비었는지 확인한다.
queueIsFull() : 큐가 꽉 차있는지 확인한다.
size() 큐의 사이즈를 반환한다.
enqueue(E value) : 큐에 데이터를 넣는다.
peek() : 큐의 맨 앞에 있는 데이터를 반환한다.
dequeue() : 큐의 맨 앞에 있는 데이터를 삭제한다.
이제 위의 인터페이스를 구현하는 클래스를 만든다.
import java.util.ArrayList;
import java.util.List;
public class GyungminQueueImpl<E> implements GyungminQueue<E> {
final static int MAX_SIZE = 10;
int size;
List<E> queue;
public GyungminQueueImpl() {
this.size = 0;
this.queue = new ArrayList<E>();
}
@Override
public boolean queueIsEmpty() {
if(size == 0) return true;
return false;
}
@Override
public boolean queueIsFull() {
if(size == MAX_SIZE) return true;
return false;
}
@Override
public int size() {
return size;
}
@Override
public void enqueue(E value) {
if(queueIsFull()) {
throw new IllegalStateException("Queue is full");
}
else {
queue.add(value);
size++;
}
}
@Override
public E peek() {
if(queueIsEmpty()) {
throw new IllegalStateException("Queue is empty");
}
else {
return queue.get(0);
}
}
@Override
public E dequeue() {
if(queueIsEmpty()) {
throw new IllegalStateException("Queue is empty");
}
else {
E result = queue.get(0);
queue.remove(0);
size--;
return result;
}
}
}
테스트를 위해서 MAX_SIZE를 10으로 작게 설정해주었다.
queueIsEmpty() , queueIsFull()를 이용해서 enqueue, dequeue, peek과정에서 IllegalStateException을 던져주었다.
이를 테스트 해본 함수다.
public class GyungminQueueTest {
public static void main(String[] args) {
GyungminQueue<Integer> queue = new GyungminQueueImpl<>();
for(int n = 1; n <= 10; n++) {
queue.enqueue(n);
}
// queue.enqueue(11);
System.out.println("queue peek() test " + queue.peek());
for(int n = 1; n <= 10; n++) {
System.out.println("queue dequeue() test " + queue.dequeue());
}
System.out.println("now queue size: " + queue.size());
// queue.dequeue();
// System.out.println(queue.peek());
}
}
10까지 데이터를 넣어주고 뒤에 11번째 데이터를 삽입하려고 시도하면?

이렇게 Exception이 발생하는 것을 확인할 수 있다.
peek()과 dequeue() 테스트를 해보면 다음과 같이 정상 출력된다.

dequeue가 10번 되어 사이즈가 0인상태에서 다시한번 dequeue를 시도하면

Exception이 발생된다.

마찬가지로 queue의 사이즈가 0일때 peek을 시도해도 위와같이 Exception이 발생함을 확인할 수 있다.
'공부기록 > 자료구조' 카테고리의 다른 글
[자료구조] 그래프 (Graph) (1) | 2024.02.25 |
---|---|
[C언어/자료구조] 자료구조와 스택(stack) (0) | 2020.09.16 |