🤔 Queue는 무엇인가요??


Queue는 사전적 의미로는 (무엇을 기다리는 사람, 자동차 등의) 줄 또는 대기 행렬이라는 의미로 흔히 놀이동산 대기줄, 게임에서 '큐가 안잡혀요' 할 때 큐. 정도 생각하면 될 것이다.
여기서 비유를 든 예시를 잘 살펴보면, 모두 먼저온 사람이 먼저 (게임 혹은 놀이기구) 사용하는 것을 알 수 있다.

즉, Queue는 먼저 들어온 데이터를 우선 처리하는 자료구조이다.(FIFO - Firtst In First Out)

※반례로 stack은 LIFO(Last In First Out)구조로 늦게 들어온 데이터를 우선 처리

😎 Queue의 특징


  • 큐는 먼저 들어온 데이터를 먼저 처리하는 자료구조로 FIFO(First In First Out) 구조를 가진다.
  • 두 개의 입출력 방향을 가지는 데, 데이터가 들어오는 방향나가는 방향다르다
    • ※ stack은 단 방향으로 들어오는 방향이 곧 나가는 방향과 일치
    • 큐는 Front(프론트), rear(리어) 라는 이름으로 각 끝을 지정해
      Front는 삭제 연산을, rear는 삽입 연산만 수행

그럼 Queue는 언제 사용하는가?

  • 그래프의 넓이 우선 탐색(BFS)에서 사용된다.
  • 컴퓨터 buffer(버퍼)에서 사용되는 데, 이를 조금 더 설명하자면,

큐를 사용하는 사례에는 프린터 인쇄 과정이 있다.

  1. 문서를 작성한 후 출력을 하게 되면 해당 문서는 인쇄 작업(임시 기억 장치의) Queue에 들어감

  2. 프린터기는 인쇄 작업 Queue에 들어온 순서대로 출력

해당 사례처럼 컴퓨터 장비들 사이에서 데이터를 전송할 때 Buffer를 사용하는 데,
이때 Queue가 Buffer처럼 수행할 수 있다.

이를 좀 더 설명해보자면,

  • CPU와 프린터기의 속도 차이가 난다.
  • 속도가 빠른 CPU가 먼저 문서처리를 수행한 후 해당 출력작업을 Queue에 넣는다.
  • 프린터기가 Queue에서 출력 작업을 받아 인쇄를 수행한다.

Buffer는 데이터가 임시로 저장되는 임시 메모리 영역으로 데이터를 다른 곳으로 전송할 때 사용되는데, 이때 데이터의 속도가 다르거나 처리량이 다른 장비들 간의 데이터 전송을 조절할 때 사용된다.

😊 Queue 사용법 정리


🥓 Queue 선언하기

import java.util.LinkedList;
import java.util.Queue;

Queue<String> queue = new LinkedList<>();

대게 Java에서 Queue를 사용할 때는 LinkedList로 많이 구현한다.
하지만, Queue 인터페이스를 구현하는 ArrayDequePriorityQueue도 상황에 맞게 사용한다.

🧇 Queue에 요소(element) 추가

import java.util.LinkedList;
import java.util.Queue;

Queue<String> queue = new LinkedList<>();

queue.offer("box1"); // queue에 값 box1를 추가
     //or
queue.add("box2");  // queue에 값 box2를 추가


크기가 5인 큐에 현재 box1box2 가 추가된 모습

큐는 선형 자료구조로, 해당 그림과 같이 되어있으며 큐는 양방향 입출 구조로 되어 있어
삽입되는 방향과 삭제되는 방향이 서로 다릅니다.
Typemethod설명
booleanadd(E e)용량제한을 위반하지 않고 즉시 수행할 수 있는 경우 해당 요소를 큐에 삽입,
성공시 True, 사용할 수 있는 공간이 없을 경우 IllegalStateException 반환
booleanoffer(E e)용량제한을 위반하지 않고 즉시 수행할 수 있는 경우 해당 요소를 큐에 삽입,
성공 시 True, 실패시 False를 반환한다.

여기서 용량제한 위반이란??
violating capacity restrictions로, 한계 용량 제한을 위반하는 것을 말합니다.
즉, 큐가 최대 용량에 도달해 요소를 추가하지 못하는 상황

큐는 특정한 용량을 가지고 있고 이 용량이 곧 큐가 저장할 수 있는 요소의 최대 개수를 의미합니다.
만약 최대 개수에 도달하였는데, 요소를 추가한다면 위의 add() 메서드 처럼 IllegalStateException이 발생할 수 있는 것입니다.

만약 크기가 5인 큐가 있다고 가정하면, 이미 5만큼 차있는 큐에 요소를 추가하게 되면 용량제한 위반으로 요소를 추가할 수 없는 상황이 될 수 있는 것입니다.

🍿 Queue에 요소(element) 삭제

import java.util.LinkedList;
import java.util.Queue;

Queue<String> queue = new LinkedList<>();

queue.offer("box1"); // queue에 값 box1를 추가
     //or
queue.add("box2");  // queue에 값 box2를 추가

System.out.println(queue.poll()); 	// box1 출력(맨 앞 요소)
System.out.println(queue.remove()); // box2 출력(box1이 제건 된 다음 앞 요소)
System.out.println(queue);			// [] 출력(빈 배열)

typemethod설명
Elementpoll()큐에서 현재 첫번째 값을 제거한 후 해당 값을 반환하며, 큐가 비어있을 경우 null을 반환
Elementremove()큐에서 현재 첫번째 값을 제거한 후 해당 값을 반환
단, 큐가 비어있을 경우 NoSuchElementException 예외 처리
Voidclear()큐 안에 있는 모든 요소를 제거

여기서 문제가 존재한다. 바로 Queue인터페이스에는 clear() 메서드가 존재하지 않기 때문에 위와 같이 LinkedList를 Queue로 타입 캐스팅하여 사용하게 되는 경우 사용할 수 없다.

LinkedList를 객체로 만들었지만, 타입 캐스팅을 Queue로 한다면, Queue에 존재하는 메서드만 사용할 수 있기 때문 그렇다면 어떻게 하면 clear()메서드를 사용할 수 있는가?

LinkedList<String> queue = new LinkedList<>(); //이걸로 선언하면 된다.

🍔 Queue에 요소 검색

import java.util.LinkedList;
import java.util.Queue;

Queue<String> queue = new LinkedList<>();

queue.offer("box1"); // queue에 값 box1를 추가
     //or
queue.add("box2");  // queue에 값 box2를 추가

System.out.println(queue.peek()); 		// box1 출력(맨 앞 요소)
System.out.println(queue.element()); 	// box1 출력(맨 앞 요소_
System.out.println(queue);				// [box1, box2] 출력(빈 배열)

//만약 여기 빈 큐에 peek()와 element()를 사용하게 될 시
Queue<String> queue2 = new LinkedList<>();
System.out.println(queue2.peek());		// null 출력
System.out.println(queue2.element());	// NoSuchElementException 출력
typemethod설명
Elementpeek()큐에서 현재 첫번째 값을 제거하지 않고 반환하며, 큐가 비어있을 경우 null을 반환
Elementelement()큐에서 현재 첫번째 값을 제거하지 않고 반환하며,
단, 큐가 비어있을 경우 NoSuchElementException 예외 처리

즉, 이를 정리한다면 아래와 같이 정리할 수 있겠다.

예외 발생값 반환
요소 추가add(E e)offer(E e)
요소 삭제remove()poll()
요소 검색element()peek()

💜 참고자료


JAVA SE 8 Queue 공식문서

[Java/자료구조] 큐 (Queue) 정리

[Java] 큐(Queue) 자료구조 정리

profile
ABAPER를 꿈꾸는 개발자

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN