์ถ์ฒ
ChatGPT
์๋ฐ 8 ์์ค์ฝ๋
PriorityQueue๋ ์๋ฐ์ ํ(queue) ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ํด๋์ค ์ค ํ๋๋ก, ์ฐ์ ์์์ ๋ฐ๋ผ ์์๋ค์ ๊ด๋ฆฌํ๋ ํ์ด๋ค. PriorityQueue๋ ํ(Heap) ์๋ฃ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋ฉฐ, ์ฝ์ ๋ ์์๋ค์ ํน์ ์ฐ์ ์์์ ๋ฐ๋ผ ์ ๋ ฌํ์ฌ, ๊ฐ์ฅ ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง ์์๊ฐ ๋จผ์ ์ฒ๋ฆฌ๋๋๋ก ํ๋ค.
1. PriorityQueue์ ์ฃผ์ ํน์ง
์ฐ์ ์์ ๊ธฐ๋ฐ
PriorityQueue๋ ์ผ๋ฐ์ ์ธ ํ์ ๋ฌ๋ฆฌ, ์์๋ค์ด ์ฐ์ ์์์ ๋ฐ๋ผ ์ ๋ ฌ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌ๋๋ฉฐ, Comparator๋ฅผ ์ ๊ณตํ๋ฉด ์ฌ์ฉ์ ์ ์ ์ฐ์ ์์๋ก ์ ๋ ฌํ ์ ์๋ค.
ํ(Heap) ์๋ฃ๊ตฌ์กฐ
๋ด๋ถ์ ์ผ๋ก ์ด์ง ํ(Binary Heap) ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํด ์์๋ฅผ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ค. ํ์ ์์ ์ด์ง ํธ๋ฆฌ์ ํ ์ข ๋ฃ๋ก, ํธ๋ฆฌ์์ ๋ถ๋ชจ ๋ ธ๋๊ฐ ์์ ๋ ธ๋๋ณด๋ค ์ฐ์ ์์๊ฐ ๋์ ํน์ง์ ๊ฐ์ง๋ค. ์ด๋ฅผ ํตํด O(log n)์ ์๊ฐ ๋ณต์ก๋๋ก ์ฝ์ ๊ณผ ์ญ์ ๊ฐ ์ด๋ฃจ์ด์ง๋ค.
์ ๋ ฌ ์์
PrioriotyQueue๋ ํ์ ์ ๋ ฌ ์์๋ฅผ ๋ช ์์ ์ผ๋ก ๋ณด์ฅํ์ง ์๋๋ค. ์ฆ, ์์๋ค์ด ๋ด๋ถ์ ์ผ๋ก๋ ์ ๋ ฌ๋์ง๋ง, toString()์ด๋ ๋ฐ๋ณต์๋ฅผ ํตํด ์ํํ ๋๋ ์์๊ฐ ๋ณด์ฅ๋์ง ์๋๋ค. ๋ค๋ง, ํ์ ์ฒซ ๋ฒ์งธ ์์๋ ํญ์ ์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋์ ์์์ด๋ค.
null ์์ ํ์ฉ ์ ํจ
PriorityQueue๋ null ์์๋ฅผ ํ์ฉํ์ง ์๋๋ค. ์ด๋ ์ฐ์ ์์ ๋น๊ต์ null ๊ฐ์ด ๋ฌธ์ ๊ฐ ๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
2. PriorityQueue์ ๊ธฐ๋ณธ ๋์
์ฝ์ ( offer ๋๋ add() ๋ฉ์๋ )
ํ์ ์์๋ฅผ ์ฝ์ ํ ๋, ํด๋น ์์๋ ํ์ ์ด์ฉํด ์ ์ ํ ์์น์ ๋ฐฐ์น๋์ด ์ฐ์ ์์๋ฅผ ์ ์งํ๋ค. ์ฝ์ ๋ ์์๋ ํ์ ํน์ฑ์ ๋ฐ๋ผ ๋ถ๋ชจ ๋ ธ๋์ ๋น๊ต๋์ด ์ ์ ํ ์์น๋ก ์ฌ๋ผ๊ฐ๊ฑฐ๋ ๋ด๋ ค๊ฐ๋ค.
์ ๊ฑฐ ( poll ๋ฉ์๋ )
ํ์์ ์์๋ฅผ ์ ๊ฑฐํ ๋, ๊ฐ์ฅ ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง ์์๊ฐ ๋ฐํ๋๊ณ ์ ๊ฑฐ๋๋ค. ํ์์ ๋ง์ง๋ง ์์๊ฐ ์ฒซ ๋ฒ์งธ ์์น๋ก ์ด๋ํ ํ, ๋ค์ ํ์ ํน์ฑ์ ์ ์งํ๊ธฐ ์ํด ํ ๋ค์ด(Heap Down) ์์ ์ด ์งํ๋๋ค.
์กฐํ ( peek ๋ฉ์๋ )
ํ์ ๋งต ์ ์์(์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋์ ์์)๋ฅผ ๋ฐํํ๋, ํ์์ ์ ๊ฑฐํ์ง๋ ์๋๋ค.
3. PriorityQueue ๋ฉ์๋
1. ์ฝ์ ๋ฐ ์ญ์
boolean offer(E e)
ํ์ ์์๋ฅผ ์ฝ์ ํ๋ฉฐ, ์ฑ๊ณต์ ์ผ๋ก ์ฝ์ ๋๋ฉด true๋ฅผ ๋ฐํ๋๋ค.
E poll
ํ์์ ์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋์ ์์๋ฅผ ์ ๊ฑฐํ๊ณ ๋ฐํํ๋ค. ํ๊ฐ ๋น์ด ์์ผ๋ฉด null์ ๋ฐํํ๋ค.
2. ์กฐํ
E peek()
ํ์ ์ฒซ ๋ฒ์งธ ์์(์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋์ ์์)๋ฅผ ๋ฐํํ์ง๋ง, ํ์์ ์ ๊ฑฐํ์ง๋ ์๋๋ค. ํ๊ฒ ๋น์ด ์์ผ๋ฉด null์ ๋ฐํํ๋ค.
3. ๊ธฐํ ๋ฉ์๋
int size()
ํ์ ์๋ ์์์ ๊ฐ์๋ฅผ ๋ฐํํ๋ค.
boolean isEmpty()
ํ๊ฐ ๋น์ด ์๋์ง ํ์ธํ๋ค.
4. PriorityQueue์ ๋ด๋ถ ๊ตฌํ
PriorityQueue๋ ํ(Heap) ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํด ๊ตฌํ๋๋ฉด, ๋ด๋ถ์ ์ผ๋ก ๋์ ๋ฐฐ์ด(Object[])์ ์ฌ์ฉํด ์์๋ค์ ์ ์ฅํ๋ค. ํ์ ์์ ์ด์ง ํธ๋ฆฌ๋ก ๊ตฌ์ฑ๋๋ฉฐ, ์ต์ ํ(min-heap) ๋๋ ์ต๋ ํ(max-heap)์ผ๋ก ๊ตฌํ๋ ์ ์๋ค. PriorityQueue๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ต์ ํ์ผ๋ก ๋์ํ๋ค.
1. ๋ฐฐ์ด์ ์ด์ฉํ ํ ๊ตฌํ
PriorityQueue๋ ๋ฐฐ์ด์ ์ฌ์ฉํด ํธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ํํํ๋ค. ๋ฐฐ์ด ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํด ๋ถ๋ชจ์ ์์๊ฐ์ ๊ด๊ณ๋ฅผ ์ฝ๊ฒ ๊ณ์ฐํ ์ ์๋ค.
- ๋ถ๋ชจ ๋ ธ๋ ์ธ๋ฑ์ค : (i-1) /2
- ์ผ์ชฝ ์์ ๋ ธ๋ ์ธ๋ฑ์ค : 2 * i + 1
- ์ผ์ชฝ ์์ ๋ ธ๋ ์ธ๋ฑ์ค : 2 * i + 1
2. ์ฝ์ ์ฐ์ฐ
PriorityQueue์ ์์๋ฅผ ์ฝ์ ํ ๋๋ ๋ฐฐ์ด์ ๋ง์ง๋ง์ ์์๋ฅผ ์ฝ์ ํ ํ, ํ ์ (Heap Up) ์์ ์ ํตํด ์ ์ ํ ์์น๋ก ์ด๋์ํจ๋ค. ์ด๋ ๋ถ๋ชจ ๋ ธ๋์ ๋น๊ตํด ์ ์ ํ ์์น์ ์์ ๋๊ฐ์ง ๋ฐ๋ณต๋๋ค.
์๋ฐ 8 PriorityQueue ์์ค์ฝ๋
/**
* Inserts the specified element into this priority queue.
*
* Returns:
* true (as specified by Collection.add)
* Throws:
* ClassCastException – if the specified element cannot be
* compared with elements currently in this priority queue
* according to the priority queue's ordering
* Throws:
* NullPointerException – if the specified element is null
*/
public boolean add(E e) {
return offer(e);
}
/**
* Inserts the specified element into this priority queue.
*
* Returns:
* true (as specified by Queue.offer)
* Throws:
* ClassCastException – if the specified element cannot be
* compared with elements currently in this priority queue
* according to the priority queue's ordering
* Throws:
* NullPointerException – if the specified element is null
*/
public boolean offer(E e) {
if (e == null)
throw new NullPointerException();
modCount++;
int i = size;
if (i >= queue.length)
grow(i + 1);
size = i + 1;
if (i == 0)
queue[0] = e;
else
siftUp(i, e);
return true;
}
/**
* Inserts item x at position k, maintaining heap invariant by
* promoting x up the tree until it is greater than or equal to
* its parent, or is the root.
*
* To simplify and speed up coercions and comparisons. the
* Comparable and Comparator versions are separated into different
* methods that are otherwise identical. (Similarly for siftDown.)
*
* Params:
* k – the position to fill
* x – the item to insert
*/
private void siftUp(int k, E x) {
if (comparator != null)
siftUpUsingComparator(k, x);
else
siftUpComparable(k, x);
}
@SuppressWarnings("unchecked")
private void siftUpUsingComparator(int k, E x) {
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (comparator.compare(x, (E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = x;
}
@SuppressWarnings("unchecked")
private void siftUpComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>) x;
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (key.compareTo((E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = key;
}
3. ์ญ์ ์ฐ์ฐ
๊ฐ์ฅ ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง ์์(๋ฃจํธ ๋ ธ๋)๋ฅผ ์ญ์ ํ ๋๋ ๋ฐฐ์ด์ ์ฒซ ๋ฒ์งธ ์์๋ฅผ ์ ๊ฑฐํ๊ณ , ๋ฐฐ์ด์ ๋ง์ง๋ง ์์๋ฅผ ๋ฃจํธ ์์น๋ก ์ด๋์ํจ ํ, ํ ๋ค์ด(Heap Down) ์์ ์ ์ํํด ํ์ ํน์ฑ์ ์ ์งํ๋ค.
@SuppressWarnings("unchecked")
public E poll() {
if (size == 0)
return null;
int s = --size;
modCount++;
E result = (E) queue[0];
E x = (E) queue[s];
queue[s] = null;
if (s != 0)
siftDown(0, x);
return result;
}
/**
* Inserts item x at position k, maintaining heap invariant by
* demoting x down the tree repeatedly until it is less than or
* equal to its children or is a leaf.
*
* Params:
* k – the position to fill
* Params:
* x – the item to insert
*/
private void siftDown(int k, E x) {
if (comparator != null)
siftDownUsingComparator(k, x);
else
siftDownComparable(k, x);
}
@SuppressWarnings("unchecked")
private void siftDownUsingComparator(int k, E x) {
int half = size >>> 1;
while (k < half) {
int child = (k << 1) + 1;
Object c = queue[child];
int right = child + 1;
if (right < size &&
comparator.compare((E) c, (E) queue[right]) > 0)
c = queue[child = right];
if (comparator.compare(x, (E) c) <= 0)
break;
queue[k] = c;
k = child;
}
queue[k] = x;
}
@SuppressWarnings("unchecked")
private void siftDownComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>)x;
int half = size >>> 1; // loop while a non-leaf
while (k < half) {
int child = (k << 1) + 1; // assume left child is least
Object c = queue[child];
int right = child + 1;
if (right < size &&
((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
c = queue[child = right];
if (key.compareTo((E) c) <= 0)
break;
queue[k] = c;
k = child;
}
queue[k] = key;
}
4. ํ์ฅ ๋ฐ ๋์ ๋ฐฐ์ด ๊ด๋ฆฌ
PriorityQueue๋ ๋ด๋ถ ๋ฐฐ์ด์ด ๊ฐ๋ ์ฐจ๋ฉด ์๋์ผ๋ก ๋์ ๋ฐฐ์ด ํ์ฅ์ ์ํํ๋ค. ๋ฐฐ์ด ํฌ๊ธฐ๋ ๊ธฐ์กด ํฌ๊ธฐ์ 1.5๋ฐฐ๋ก ์ฆ๊ฐํ๋ฉฐ, ์ด๋ Arrays.copyOf() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์๋ก์ด ๋ฐฐ์ด๋ก ๋ณต์ฌ๋๋ค.
/**
* Increases the capacity of the array.
*
* Params:
* minCapacity – the desired minimum capacity
*/
private void grow(int minCapacity) {
int oldCapacity = queue.length;
// Double size if small; else grow by 50%
int newCapacity = oldCapacity + ((oldCapacity < 64) ?
(oldCapacity + 2) :
(oldCapacity >> 1));
// overflow-conscious code
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
queue = Arrays.copyOf(queue, newCapacity);
}
5. PriorityQueue์ ์์
import java.util.PriorityQueue;
public class PriorityQueueExample {
public static void main(String[] args) {
// ๊ธฐ๋ณธ์ ์ผ๋ก Integer ํ์
์ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌ๋จ (์ต์ ํ)
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(10);
pq.offer(20);
pq.offer(15);
// ์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋์ ์์(10)๋ฅผ ๋ฐํํ๊ณ ์ ๊ฑฐ
System.out.println("Poll: " + pq.poll()); // ์ถ๋ ฅ: 10
// ํ์ ์ฒซ ๋ฒ์งธ ์์(15)๋ฅผ ์กฐํํ์ง๋ง ์ ๊ฑฐํ์ง ์์
System.out.println("Peek: " + pq.peek()); // ์ถ๋ ฅ: 15
// ํ์ ๋จ์ ์์๋ค
System.out.println("Remaining elements: " + pq); // ์ถ๋ ฅ: [15, 20]
}
}
6. Comparator๋ฅผ ์ฌ์ฉํ PriorityQueue
PriorityQueue๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ฐ ์์(์ค๋ฆ์ฐจ์)๋ก ์์๋ฅผ ์ ๋ ฌํ์ง๋ง, Comparator๋ฅผ ์ฌ์ฉํด ์ฌ์ฉ์ ์ ์ ์ ๋ ฌ ๊ธฐ์ค์ ์ ์ฉํ ์ ์๋ค. ์๋ฅผ ๋ค์ด, ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ PriorityQueue๋ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ ์ ์๋ค.
import java.util.PriorityQueue;
import java.util.Comparator;
public class CustomPriorityQueueExample {
public static void main(String[] args) {
// ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ์ ์ํ Comparator๋ฅผ ์ฌ์ฉํ PriorityQueue
PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());
pq.offer(10);
pq.offer(20);
pq.offer(15);
// ์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋์ ์์(20)๋ฅผ ๋ฐํํ๊ณ ์ ๊ฑฐ
System.out.println("Poll: " + pq.poll()); // ์ถ๋ ฅ: 20
// ํ์ ์ฒซ ๋ฒ์งธ ์์(15)๋ฅผ ์กฐํํ์ง๋ง ์ ๊ฑฐํ์ง ์์
System.out.println("Peek: " + pq.peek()); // ์ถ๋ ฅ: 15
// ํ์ ๋จ์ ์์๋ค
System.out.println("Remaining elements: " + pq); // ์ถ๋ ฅ: [15, 10]
}
}
7. PriorityQueue์ ์๊ฐ ๋ณต์ก๋
์ฝ์ offer() : O(log n)
์๋ก์ด ์์๊ฐ ํ์ ์ฝ์ ๋ ๋, ํ์ ํน์ฑ์ ์ ์งํ๊ธฐ ์ํด ํ ์ (Heap Up) ์์ ์ด ์ํ๋๋ค.
์ญ์ poll() : O(log n)
๋ฃจํธ ์์๋ฅผ ์ ๊ฑฐํ ํ, ๋ง์ง๋ง ์์๊ฐ ๋ฃจํธ๋ก ์ด๋ํ๊ณ ํ ๋ค์ด (Heap Down) ์์ ์ด ์ํ๋๋ค.
์กฐํ peek() : O(1)
์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋์ ์์๋ฅผ ๋ฐํํ๋ ์์ ์ ํ์์ ์ฒซ ๋ฒ์งธ ์์๋ฅผ ๋ฐํํ๋ฏ๋ก ์์ ์๊ฐ์ ์ด๋ฃจ์ด์ง๋ค.
8. PriorityQueue์ ๋จ์
์ ๋ ฌ๋ ์์๋ก์ ๋ฐ๋ณต์ ์ ๊ณต ์ ํจ
PriorityQueue๋ ๋ด๋ถ์ ์ผ๋ก ์ ๋ ฌ๋์ด ์์ง๋ง, ํ์ ์์๋ฅผ ์ํํ ๋๋ ์ ๋ ฌ๋ ์์๋ก ์ ๊ณต๋์ง ์๋๋ค. ๋ฐ๋ผ์ ํ๋ฅผ ์ํํ๋ฉด์ ์ฐ์ ์์์ ๋ฐ๋ผ ์์๋ฅผ ์ป์ผ๋ ค๋ฉด, poll() ๋ฉ์๋๋ฅผ ๋ฐ๋ณต ํธ์ถํด์ผ ํ๋ค.
null ํ์ฉ ์ ํจ
PriorityQueue๋ null ๊ฐ์ ํ์ฉํ์ง ์๋๋ค. null์ ์ฝ์ ํ๋ ค๊ณ ํ๋ฉด NullPointerException์ด ๋ฐ์ํ๋ค.
'๋น ๊ตฌ๋ฉ ์ฑ์ฐ๊ธฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๋ฃ๊ตฌ์กฐ] ํด์ ์ถฉ๋ Hash Collision (1) | 2024.10.01 |
---|---|
[Java] Retrofit2์์ Annotation์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ ์ดํผ๊ธฐ (1) | 2024.09.23 |
[์๋ฃ ๊ตฌ์กฐ]์ด์ง ํ Binary Heap (1) | 2024.09.18 |
[์๋ฃ ๊ตฌ์กฐ][Java] ํ Heap (1) | 2024.09.17 |
[์๊ณ ๋ฆฌ์ฆ] ์์ ์ ์ธ ์ ๋ ฌ Stable Sorting (1) | 2024.09.15 |