πŸ§ͺ 컴퓨터과학 : CS

[자료ꡬ쑰] Priority Queue (μš°μ„ μˆœμœ„ 큐) 인터뷰 λŒ€λΉ„

개발자 HOON 2022. 10. 23. 17:08

 

πŸ’‘ 1. μš°μ„ μˆœμœ„ 큐(Priority Queue)λž€?

 

μš°μ„  '큐'λŠ” μ„ μž…μ„ μΆœμ˜ ꡬ쑰λ₯Ό κ°€μ§„ μ„ ν˜• μžλ£Œκ΅¬μ‘°μ΄λ‹€. 큐에 λ“€μ–΄μ˜¨ μˆœμ„œλ₯Ό μš°μ„ μˆœμœ„λ‘œ κ°–λŠ” 큐인 것이닀.

μš°μ„ μˆœμœ„ νλŠ” 일반적으둜 λ¨Όμ € λ“€μ–΄μ˜¨ μˆœμ„œλŒ€λ‘œ λΉ μ Έλ‚˜μ˜€λŠ” 것이 μ•„λ‹ˆλΌ, 큐 λ‚΄λΆ€μ˜ μ›μ†Œ 쀑 κ°€μž₯ μš°μ„ μˆœμœ„κ°€ κ°€μž₯ 높은 μš”μ†ŒλΆ€ν„° λΉ μ Έ λ‚˜μ˜€λŠ” 큐λ₯Ό μ˜λ―Έν•œλ‹€.

 

 

πŸ’‘ 2. μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•˜λŠ” 방법

 

 μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•˜λŠ” 방법은 μ„Έ 가지이닀.

각각 λ°°μ—΄(Array), μ—°κ²°λ¦¬μŠ€νŠΈ(LinkedList), νž™(Heap)을 μ‚¬μš©ν•˜λŠ” 방법인데 κ·Έ 쀑 일반적으둜 μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•˜λŠ” 방법은 Heap을 μ‚¬μš©ν•˜λŠ” 방식이닀. μ™œ μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•  λ•Œ Heap을 μ‚¬μš©ν•˜λŠ” μ§€λŠ” λ°”λ‘œ μ‹œκ°„λ³΅μž‘λ„μ— μžˆλ‹€.

 

λ‹€μŒμ€ 각각의 자료ꡬ쑰λ₯Ό μ‚¬μš©ν•΄ μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•˜λŠ” 방법이닀.

 

1) λ°°μ—΄(Array)λ₯Ό μ΄μš©ν•΄μ„œ μš°μ„ μˆœμœ„ 큐λ₯Ό λ§Œλ“€κΈ°.

λ°°μ—΄λ‘œ μš°μ„ μˆœμœ„ 큐λ₯Ό λ§Œλ“œλŠ” 방법은, μ •λ ¬λœ 배열을 μ΄μš©ν•˜λŠ” 방법 / μ •λ ¬λ˜μ§€ μ•Šμ€ 배열을 μ΄μš©ν•˜λŠ” 방법 2가지이닀.
νλŠ” 기본적으둜 μ‚½μž…κ³Ό μ‚­μ œ 연산이 μžˆμœΌλ―€λ‘œ, 이 두 κ°€μ§€ 연산을 μ–΄λ–»κ²Œ λ§Œλ“€ 수 μžˆμ„μ§€ μƒκ°ν•΄λ³΄μž.

- μ •λ ¬λœ λ°°μ—΄λ‘œ μš°μ„ μˆœμœ„ 큐 λ§Œλ“€κΈ° (μš°μ„ μˆœμœ„λ₯Ό keyκ°’μœΌλ‘œ μ •λ ¬λœ λ°°μ—΄)
μ‚­μ œμ˜ 경우, μš°μ„ μˆœμœ„ μˆœμ„œλŒ€λ‘œ 정렬이 λ˜μ–΄ μžˆμœΌλ―€λ‘œ, κ°€μž₯ μ•žμ˜ μ›μ†Œλ₯Ό return ν•˜λ©΄ λœλ‹€. λ”°λΌμ„œ μ‚­μ œμ˜ μ‹œκ°„λ³΅μž‘λ„λŠ” O(1)
μ‚½μž…μ˜ 경우, μ‚½μž…ν•  μš”μ†Œμ˜ μš°μ„ μˆœμœ„κ°€ μ–΄λŠ μœ„μΉ˜μ— λ“€μ–΄κ°€μ•Ό ν•˜λŠ”μ§€ μš”μ†Œ ν•˜λ‚˜ν•˜λ‚˜ λΉ„κ΅ν•΄μ„œ μ°Ύμ•„μ•Ό ν•˜λ―€λ‘œ, μ΅œμ•…μ˜ 경우 λ°°μ—΄μ˜ 길이인 N만큼의 연산이 ν•„μš”ν•˜λ‹€. λ”°λΌμ„œ μ‚½μž…μ˜ μ‹œκ°„λ³΅μž‘λ„λŠ” O(N)

- μ •λ ¬λ˜μ§€ μ•Šμ€ λ°°μ—΄λ‘œ μš°μ„ μˆœμœ„ 큐 λ§Œλ“€κΈ°
μ‚­μ œμ˜ 경우, λ°°μ—΄ λ‚΄λΆ€λŠ” μ •λ ¬λ˜μ–΄ μžˆμ§€ μ•ŠκΈ° λ•Œλ¬Έμ— λ°°μ—΄ λ‚΄λΆ€μ˜ λͺ¨λ“  μ›μ†Œλ₯Ό 비ꡐ해 κ°€μž₯ 높은 μš°μ„ μˆœμœ„μ˜ 값을 μ°Ύμ•„ μ œκ±°ν•΄μ•Ό ν•œλ‹€. 무쑰건 N번의 연산을 거쳐야 ν•˜λ―€λ‘œ μ‚­μ œμ˜ μ‹œκ°„λ³΅μž‘λ„λŠ” O(N)에 ν•΄λ‹Ήν•œλ‹€.
μ‚½μž…μ˜ 경우, λ°°μ—΄ λ‚΄λΆ€λŠ” μ •λ ¬λ˜μ–΄ μžˆμ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, 별닀λ₯Έ κ·œμΉ™ 없이 λ°°μ—΄μ˜ 끝 뢀뢄에 μš”μ†Œλ₯Ό μ‚½μž…ν•˜λ©΄ λœλ‹€. λ”°λΌμ„œ μ‚½μž…μ˜ μ‹œκ°„ λ³΅μž‘λ„λŠ” O(1)이닀.

 

2) μ—°κ²°λ¦¬μŠ€νŠΈ(LinkedList)λ₯Ό μ΄μš©ν•΄μ„œ μš°μ„ μˆœμœ„ 큐λ₯Ό λ§Œλ“€κΈ°.

μ—°κ²°λ¦¬μŠ€νŠΈλ‘œ μš°μ„ μˆœμœ„ 큐λ₯Ό λ§Œλ“œλŠ” 방법 μ—­μ‹œ, μ •λ ¬λœ μ—°κ²°λ¦¬μŠ€νŠΈλ₯Ό μ΄μš©ν•˜λŠ” 방법 / μ •λ ¬λ˜μ§€ μ•Šμ€ μ—°κ²°λ¦¬μŠ€νŠΈλ₯Ό μ΄μš©ν•˜λŠ” 방법 2가지이닀.
λ§ˆμ°¬κ°€μ§€λ‘œ μ‚½μž…κ³Ό μ‚­μ œ 연산을 μ–΄λ–»κ²Œ λ§Œλ“€ 수 μžˆμ„μ§€ μƒκ°ν•΄λ³΄μž.

- μ •λ ¬λœ μ—°κ²°λ¦¬μŠ€νŠΈλ‘œ μš°μ„ μˆœμœ„ 큐 λ§Œλ“€κΈ°
μ‚­μ œμ˜ 경우, λ°°μ—΄κ³Ό λ™μΌν•˜κ²Œ κ°€μž₯ μ•žμ˜ μ›μ†Œλ₯Ό μ œκ±°ν•˜λ©΄ λœλ‹€. O(1)
μ‚½μž…μ˜ 경우, λ°°μ—΄κ³Ό λ™μΌν•˜κ²Œ μ‚½μž…ν•˜κ³ μž ν•˜λŠ” μ›μ†Œκ°€ μ–΄λŠ μžλ¦¬μ— λ“€μ–΄κ°€μ•Ό ν•˜λŠ”μ§€ μ—°κ²°λ¦¬μŠ€νŠΈ λ‚΄λΆ€μ˜ μ›μ†Œλ₯Ό μ§€λ‚˜κ°€λ©° 탐색해야 ν•œλ‹€. μ΅œμ•…μ˜ 경우 N개의 μš”μ†Œλ₯Ό λͺ¨λ‘ 탐색해야 ν•˜κΈ° λ•Œλ¬Έμ— worst case의 경우 O(N)
λ°°μ—΄κ³Ό μŠ·ν•œ μ‹œκ°„λ³΅μž‘λ„λ₯Ό κ°€μ§€λ‚˜, μ—°κ²°λ¦¬μŠ€νŠΈμ˜ νŠΉμ„±μƒ 배열보닀 μ‚­μ œμ™€ μ‚½μž…μ˜ 연산이 λ‹¨μˆœν•˜κΈ° λ•Œλ¬Έμ— λ°°μ—΄λ³΄λ‹€λŠ” μœ λ¦¬ν•˜λ‹€.

- μ •λ ¬λ˜μ§€ μ•Šμ€ μ—°κ²°λ¦¬μŠ€νŠΈλ‘œ μš°μ„ μˆœμœ„ 큐 λ§Œλ“€κΈ°
μ‚­μ œμ˜ 경우, λ°°μ—΄κ³Ό λ™μΌν•˜κ²Œ μ‚­μ œν•˜κ³ μž ν•˜λŠ” μ›μ†Œλ₯Ό μ—°κ²°λ¦¬μŠ€νŠΈ λ‚΄λΆ€λ₯Ό λͺ¨λ‘ νƒμƒ‰ν•˜λ©° μ°Ύμ•„λ‚΄μ•Ό ν•œλ‹€. λ”°λΌμ„œ μ‹œκ°„λ³΅μž‘λ„λŠ” O(N)이닀.
μ‚½μž…μ˜ 경우, μ—°κ²°λ¦¬μŠ€νŠΈ 내뢀에 μ•„λ¬΄λŸ° κ·œμΉ™μ΄ μ—†μœΌλ―€λ‘œ κ°€μž₯ λ„£κΈ° μ‰¬μš΄ μœ„μΉ˜μΈ μ•žμ— μ‚½μž…ν•œλ‹€. λ”°λΌμ„œ μ‹œκ°„λ³΅μž‘λ„λŠ” O(1)이닀.
λ°°μ—΄κ³Ό λΉ„μŠ·ν•œ μ‹œκ°„λ³΅μž‘λ„λ₯Ό κ°€μ§€λ‚˜, μ—°κ²°λ¦¬μŠ€νŠΈμ˜ νŠΉμ„±μƒ 배열보닀 μ‚­μ œμ™€ μ‚½μž…μ˜ 연산이 λ‹¨μˆœν•˜κΈ° λ•Œλ¬Έμ— λ°°μ—΄λ³΄λ‹€λŠ” μœ λ¦¬ν•˜λ‹€.

 

3) νž™(Heap)을 μ΄μš©ν•΄μ„œ μš°μ„ μˆœμœ„ 큐λ₯Ό λ§Œλ“€κΈ°

νž™μ΄ 되기 μœ„ν•œ 쑰건은 2가지이닀. μ™„μ „μ΄μ§„νŠΈλ¦¬μ˜ ꡬ쑰λ₯Ό κ°€μ§€λ©°, λΆ€λͺ¨λ…Έλ“œμ™€ μžμ‹ λ…Έλ“œκ°„μ— 'ν¬κ±°λ‚˜ 같은' ν˜Ήμ€ 'μž‘κ±°λ‚˜ 같은'의 κ·œμΉ™μ„ κ°€μ§€κ³  μžˆμ–΄μ•Ό ν•œλ‹€. 이 νž™μ„ μ΄μš©ν•΄μ„œ μš°μ„ μˆœμœ„ 큐λ₯Ό λ§Œλ“œλŠ” 방법에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄μž.
μ—­μ‹œ μ‚½μž…κ³Ό μ‚­μ œμ˜ κ΄€μ μ—μ„œ 확인해보도둝 ν•˜μž.

- Heap으둜 μš°μ„ μˆœμœ„ 큐 λ§Œλ“€κΈ°
μš°μ„ , μœ„μ˜ νž™μ΄ 되기 μœ„ν•œ 쑰건에 λΆ€λͺ¨λ…Έλ“œμ™€ μžμ‹ λ…Έλ“œκ°„μ— 'ν¬κ±°λ‚˜ 같은' ν˜Ήμ€ 'μž‘κ±°λ‚˜ 같은'의 κ·œμΉ™μ„ κ°€μ§€κ³  μžˆμ–΄μ•Ό λœλ‹€.
λ”°λΌμ„œ μš°μ„ μˆœμœ„κ°€ κ°€μž₯ 큰 값이 μ˜€λ„λ‘ νž™μ΄ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€λ©΄, λ£¨νŠΈλ…Έλ“œμ— μžˆλŠ” 값을 λ¦¬ν„΄ν•˜κ³ , νŠΈλ¦¬μ—μ„œ ν•΄λ‹Ή λ…Έλ“œλ₯Ό μ‚­μ œν•˜κ³ , λ‹€μ‹œ νž™μœΌλ‘œ λ§Œλ“€λ©΄ μ‚­μ œ 연산이 λœλ‹€.

μ‚­μ œ μ—°μ‚° μ•Œκ³ λ¦¬μ¦˜μ€ λ‹€μŒκ³Ό κ°™λ‹€.
1) λ£¨νŠΈλ…Έλ“œμ˜ 값을 λ¦¬ν„΄ν•œλ‹€. (O(1))
2) κ°€μž₯ λ§ˆμ§€λ§‰ 인덱슀λ₯Ό κ°€μ§„ λ…Έλ“œλ₯Ό λ£¨νŠΈλ…Έλ“œ μžλ¦¬μ— μœ„μΉ˜μ‹œν‚¨λ‹€. (O(1))
3) λ£¨νŠΈλ…Έλ“œμ™€ 두 μžμ‹ λ…Έλ“œλ₯Ό λΉ„κ΅ν•œλ‹€. 두 μžμ‹λ…Έλ“œ 쀑 λΆ€λͺ¨λ…Έλ“œλ³΄λ‹€ μš°μ„ μˆœμœ„κ°€ 큰 λ…Έλ“œκ°€ μžˆλ‹€λ©΄ κ°€μž₯ μš°μ„ μˆœμœ„κ°€ 큰 λ…Έλ“œμ™€ 자리λ₯Ό λ³€κ²½ν•œλ‹€. 자리λ₯Ό λ³€κ²½ν•œ ν›„, λ³€κ²½ν•œ ν›„μ˜ μžμ‹κ³Όλ„ 계속 λΉ„κ΅ν•œλ‹€. μžμ‹λ³΄λ‹€ μš°μ„ μˆœμœ„κ°€ 크닀면 이 λ°˜λ³΅μ„ μ€‘λ‹¨ν•œλ‹€. (O(logN))

μ—¬κΈ°μ„œ 3번의 경우, 트리의 높이 만큼 연산이 μ§„ν–‰λ˜κ³  νž™μ€ 'μ™„μ „μ΄μ§„νŠΈλ¦¬'라고 ν–ˆμœΌλ―€λ‘œ worst case인 경우 밑이 2인 logN번의 연산을 μˆ˜ν–‰ν•œλ‹€. λ”°λΌμ„œ 1~3번의 μˆœμ„œλŒ€λ‘œ 연산을 μ§„ν–‰ν–ˆμ„ λ•Œ μ‚­μ œ μ—°μ‚°μ˜ worst caseλŠ” O(logN)의 μ‹œκ°„ λ³΅μž‘λ„λ₯Ό κ°€μ§„λ‹€.

μ‚½μž… μ—°μ‚° μ•Œκ³ λ¦¬μ¦˜μ€ λ‹€μŒκ³Ό κ°™λ‹€.
1) κ°€μž₯ λ§ˆμ§€λ§‰ 인덱슀 λ‹€μŒ μΈλ±μŠ€μ— μ‚½μž…ν•˜κ³ μž ν•˜λŠ” λ…Έλ“œλ₯Ό λ„£λŠ”λ‹€. (O(1))
2) ν•΄λ‹Ή κ°’κ³Ό λΆ€λͺ¨λ…Έλ“œμ˜ μš°μ„ μˆœμœ„λ₯Ό λΉ„κ΅ν•œλ‹€. ν•΄λ‹Ή κ°’(μžμ‹λ…Έλ“œ)이 λΆ€λͺ¨λ…Έλ“œλ³΄λ‹€ μš°μ„ μˆœμœ„κ°€ 더 λ†’λ‹€λ©΄ μ„œλ‘œ 자리λ₯Ό λ³€κ²½ν•œλ‹€. 자리λ₯Ό λ°”κΎΌ 이후에도 κ·Έ μœ„μ˜ λΆ€λͺ¨λ…Έλ“œμ™€ λΉ„κ΅ν•˜λ©°, λΆ€λͺ¨λ…Έλ“œμ˜ μš°μ„ μˆœμœ„κ°€ 더 클 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€. (O(logN))

μ‚½μž… 연산도 λ§ˆμ°¬κ°€μ§€λ‘œ, worst case인 경우 제일 λ°‘μ—μ„œ λ£¨νŠΈλ…Έλ“œκΉŒμ§€ 올라올 수 μžˆμœΌλ―€λ‘œ 트리의 λ†’μ΄λ§ŒνΌ 연산이 λœλ‹€. λ”°λΌμ„œ μ‚½μž… 연산도 O(logN)의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό κ°€μ§„λ‹€.

 

 

4) μ‹œκ°„λ³΅μž‘λ„ 비ꡐ 및 Heap 선택 이유

μš°μ„ μˆœμœ„ 큐 κ΅¬ν˜„μ— μ‚¬μš©ν•œ 자료ꡬ쑰 worst case μ‚½μž…μ—°μ‚° worst case μ‚­μ œ
μ •λ ¬λœ λ°°μ—΄ O(N) O(1)
μ •λ ¬λ˜μ§€ μ•Šμ€ λ°°μ—΄ O(1) O(N)
μ •λ ¬λœ μ—°κ²°λ¦¬μŠ€νŠΈ O(N) O(1)
μ •λ ¬λ˜μ§€ μ•Šμ€ μ—°κ²°λ¦¬μŠ€νŠΈ O(1) O(N)
Heap 자료ꡬ쑰 O(logN) O(logN)

 

λ‹€λ₯Έ μ•Œκ³ λ¦¬μ¦˜μ€ μ‚½μž…κ³Ό μ‚­μ œ 연산이 O(1), O(N)으둜 두 μ—°μ‚°κ°„ μ‹œκ°„λ³΅μž‘λ„ νŽΈμ°¨κ°€ 크닀.

반면 νž™μœΌλ‘œ κ΅¬ν˜„ν•œ μš°μ„ μˆœμœ„ νλŠ”, μ‚½μž…κ³Ό μ‚­μ œ μ—°μ‚° λͺ¨λ‘ 트리의 높이에 따라 κ²°μ •λ˜λŠ” O(logN)의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό κ°–λŠ”λ‹€.

 

μ‹œκ°„λ³΅μž‘λ„ νŽΈμ°¨κ°€ 크면 μ›μ†Œμ˜ μ–‘κ³Ό μ—°μ‚°μ˜ 양이 λŠ˜μ–΄λ‚  수둝 μ—°μ‚° μ‹œκ°„μ΄ μ˜€λž˜κ±Έλ¦°λ‹€.

λ°°μ—΄/μ—°κ²°λ¦¬μŠ€νŠΈμ˜ 경우 λ™μΌν•œ 횟수의 μ‚½μž…κ³Ό μ‚­μ œλ₯Ό ν•˜λ©΄ kN + k번, νž™μ„ μ‚¬μš©ν•œ κ²½μš°μ—” 2*klogN번 연산이 μ§„ν–‰λœλ‹€.

N의 κΈ°μšΈκΈ°λŠ” logN의 κΈ°μšΈκΈ°λ³΄λ‹€ 훨씬 κ°€νŒŒλ₯΄κΈ° λ•Œλ¬Έμ— μ›μ†Œμ˜ 양이 λŠ˜μ–΄λ‚œλ‹€λ©΄ μ‹œκ°„μ΄ 훨씬 더 많이 μ†Œμš”λ˜κ²Œ λœλ‹€.

λ”°λΌμ„œ μ‚½μž…κ³Ό μ‚­μ œ λͺ¨λ‘ O(logN)의 μ‹œκ°„λ³΅μž‘λ„κ°€ 보μž₯된 νž™μ„ μ‚¬μš©ν•˜λŠ” 것이 μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•  λ•Œ 더 μœ λ¦¬ν•˜λ‹€.

 

+ Heap에 λŒ€ν•œ μžμ„Έν•œ λ‚΄μš©μ€ μΆ”ν›„ ν¬μŠ€νŒ…ν•˜λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.