알고리즘

[PriorityQueue] 자바의 우선순위 큐 사용법

해니01_15 2025. 1. 18. 14:00

자바의 우선순위 큐 (PriorityQueue)는 Queue 인터페이스를 구현한 자료구조 중 하나로 요소들이 우선순위에 따라 정렬되고 가장 높은 순위를 가진 요소가 먼저 제거된다.  

 

[선언]

PriorityQueue<E> pq = new PriorityQueue<>(); // 기본 생성자
PriorityQueue<E> pq = new PriorityQueue<>(Comparator<E> comparator); // 사용자 정의 정렬 기준

 

[잘 사용되는 메서드]

pq.add(E e) :  큐에 요소를 추가한다. 큐의 용량이 초과하면 예외가 발생한다. 
pq.offer(E e) : 큐에 요소를 추가한다. 큐의 용량이 초과하면 false 를 반환한다. 
pq.peak() : 우선순위 큐의 최상위 요소를 확인한다. (제거 기능 X 확인 기능) 
pq.poll() : 우선순위 큐의 최상위 요소를 제거한다. 큐가 비었다면 null 을 반환한다. 
pq.remove(Object o) : 큐에서 특정 요소를 삭제한다. 삭제에 성공하면 true, 실패시 false 반환. 
pq.size() : 큐에 있는 요소의 개수를 반환한다. 
pq.isEmpty() : 큐가 비어있는지 확인 (true, false 반환) 
pq.clear() : 큐의 모든 요소를 제거한다. 
pq.contains(Object o) : 큐에 특정한 요소가 있는지 확인한다. (true, false 반환)

 

[정렬하기]

우선순위 큐는 기본적으로 가장 작은 값이 우선 순위가 높게(오름차순) 정렬된다. 

즉, 아래의 코드와 같이 어떤 식으로 숫자를 넣든 우선순위가 높은 것은 가장 작은 숫자가 된다. 

PriorityQueue<Integer> pq = new PriorityQueue<>();
        pq.add(10);
        pq.add(5);
        pq.add(20);
        
        System.out.println("가장 높은 우선순위 요소: " + pq.peek()); // 5

 

 

근데 반대로 하고 싶다면 어떻게 해야할까? 

Comparator를 이용하면 된다! 생성자를 생성할 때  new PriorityQueue<>(); 대신 new PriorityQueue<>(Comparator.reverseOrder()); 를 이용하여 우선순위 큐가 반대로 될 수 있게 해 주면 된다. 

PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());

        // 값 추가
        pq.add(10);
        pq.add(5);
        pq.add(20);

        // 가장 큰 값 확인 및 제거
        System.out.println("가장 높은 우선순위 요소: " + pq.peek()); // 20

 

근데 내가 원하는건 저런 정렬이 아니다! 새로운 정렬을 만들고싶다? 

그렇다면 입맛에 맞춰서 아래처럼 사용자 정의 정렬로  구성 하면 된다. 

PriorityQueue<Integer> custompq = new PriorityQueue<>((a, b) -> {
			if (a % 2 != b % 2) {
				return a % 2 == 0 ? 1 : -1; // a가 짝수면 뒤로, 홀수 면 앞으로
			}
			return a - b;
		});

          // 값 추가
		custompq.add(4);
		custompq.add(3);
		custompq.add(7);
		custompq.add(6);
		custompq.add(1);

		System.out.println("현재 힙 상태: " + custompq); // [1, 3, 7, 4, 6]