Computer Science/Data Structures

๐Ÿ‘ฏPriority Queue(feat. Binary Heap)

metamong 2023. 1. 9.

intro

๐Ÿ‘ฏ ์šฐ์„ ์ˆœ์œ„ ํ = '์šฐ์„ ์ˆœ์œ„๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์žฅ ๋จผ์ € ์‚ญ์ œํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ'

 

๐Ÿ‘ฏ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฌผ๊ฑด ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋ฃŒ๊ตฌ์กฐ์— ๋„ฃ์—ˆ๋‹ค๊ฐ€ ๊ฐ€์น˜๊ฐ€ ๋†’์€ ๋ฌผ๊ฑด๋ถ€ํ„ฐ ๊บผ๋‚ด์„œ ํ™•์ธํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ์ฆ‰ ๊ฐ€์น˜๋ผ๋Š” ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌํ•  ๋•Œ ์šฐ์„ ์ˆœ์œ„ ํ๋ผ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ ์‚ฌ์šฉ. ์•ž์„œ ๋ฐฐ์šด ์Šคํƒ์˜ ๊ฒฝ์šฐ ๊ฐ€์žฅ ๋‚˜์ค‘์— ์‚ฝ์ž…๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋จผ์ € ์ถ”์ถœ๋˜๊ณ , ํ์˜ ๊ฒฝ์šฐ ๊ฐ€์žฅ ๋จผ์ € ์‚ฝ์ž…๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋จผ์ € ์ถ”์ถœ๋œ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ์„ ์ˆœ์œ„ ํ๋Š” ์ง์ ‘ ์ •ํ•œ ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์ถ”์ถœ๋˜๋Š”, ์ฆ‰, ํ๋ผ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ์—์„œ ์šฐ์„ ์ˆœ์œ„๋ผ๋Š” ์–ด๋–ค ๊ธฐ์ค€์„ ์ •ํ•ด ์ด์— ์˜ํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ถœํ•˜๋Š” ๋ฐฉ์‹์ด๋ผ ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.  

 

๐Ÿ‘ฏ ์šฐ์„ ์ˆœ์œ„ ํ๋Š” ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๋‹ค. โ‘  ๋‹จ์ˆœํžˆ list๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ โ‘ก heap์„ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•œ๋‹ค. heap์˜ ๊ฒฝ์šฐ, heap์„ ์‚ฌ์šฉํ•ด์„œ, ๋‹จ์ˆœํžˆ ๋จผ์ € ๋“ค์–ด์˜ค๊ฑฐ๋‚˜ ๋‚˜์ค‘์— ๋“ค์–ด์˜จ ์ˆœ์„œ๊ฐ€ ์•„๋‹Œ, ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€, ์ฆ‰ ์ตœ๋Œ“๊ฐ’ ๋จผ์ €, ์•„๋‹ˆ๋ฉด ์ตœ์†Ÿ๊ฐ’ ๋จผ์ € ๋ฝ‘์„ ์ˆ˜ ์žˆ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ด์šฉํ•ด ํšจ์œจ์ ์ธ ์‹œ๊ฐ„ ํšจ์œจ ๋‚ด๋กœ ์—ฐ์‚ฐ ์ง„ํ–‰์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๐Ÿ‘ฏ ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์— ๋”ฐ๋ฅธ ๊ตฌํ˜„ ์‹œ๊ฐ„ ๋ณต์žก๋„ ๋น„๊ต (๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜ N)

์šฐ์„ ์ˆœ์œ„ ํ ๊ตฌํ˜„ ๋ฐฉ์‹ ์‚ฝ์ž… ์‹œ๊ฐ„ ์‚ญ์ œ ์‹œ๊ฐ„
Priority Queue list O(1) O(N)
Priority Queue heap O(logN) O(logN)

 

โ‘  list์˜ ๊ฒฝ์šฐ ์‚ฝ์ž…์€ ๋‹จ์ˆœํžˆ ๋’ค์ชฝ์— ์‚ฝ์ž…ํ•˜๋ฉด ๋˜๋ฏ€๋กœ O(1)์ด์ง€๋งŒ, ์‚ญ์ œํ•œ๋‹ค๋ฉด ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ์•„์•ผ ํ•˜๋ฏ€๋กœ O(N)์˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆผ

โ‘ก heap์˜ ๊ฒฝ์šฐ ์‚ฝ์ž…๊ณผ ์‚ญ์ œ ๋ชจ๋‘ ์ตœ์•…์˜ ๊ฒฝ์šฐ์—๋„ O(logN)์„ ๋ณด์žฅํ•œ๋‹ค. ๋”ฐ๋ผ์„œ heap์— N๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์—ˆ๋‹ค๊ฐ€ ์šฐ์„ ์ˆœ์œ„๋กœ ์ตœ๋Œ“๊ฐ’ ๋จผ์ € ๊บผ๋‚ด๊ฑฐ๋‚˜, ์ตœ์†Ÿ๊ฐ’ ๋จผ์ € ๊บผ๋‚ด๋Š” ์ž‘์—…์€ ๊ณง ์ •๋ ฌ์„ ๋œปํ•˜๊ณ , ์ด๋Š” heap sort๋ผ๊ณ ๋„ ๋ถ€๋ฅด๋ฉฐ, ๋‹น์—ฐํžˆ priority queue ์‚ญ์ œ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(logN)์ด๋ฏ€๋กœ heap sort time complexity๋Š” O(NlogN) (์•ž์„  ๋ณ‘ํ•ฉ์ •๋ ฌ๊ณผ ์‹œ๊ฐ„๋ณต์žก๋„ ๋™์ผ)

2. heap ์š”์•ฝ

โ˜๏ธ heapq python library๋ฅผ ์‚ฌ์šฉํ•˜์ž๋ฉด,

 

→ find max()๋Š” list์˜ indexing ์‚ฌ์šฉ ํ›„, heapify() ํ•จ์ˆ˜ ์‚ฌ์šฉ
(๋˜๋Š” heappop()์„ ์‚ฌ์šฉํ•˜๋ฉด ์•Œ์•„์„œ ์ตœ์ƒ๋‹จ node๋ฅผ ๋นผ์ฃผ๊ณ , heapify()๊นŒ์ง€ ์ง„ํ–‰)

 

→ insertion์€ heappush() ์‚ฌ์šฉ (์•Œ์•„์„œ max ๋˜๋Š” min heap ํ˜•์„ฑ)

 

→ heapsort()๋Š” ๋ณ„๋„ ์ •๋ ฌ ํฌ์ŠคํŒ… ์ฐธ์กฐ (heappush()์™€ heappop()์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์“ฐ๋ฉด ๋œ๋‹ค)

examples

๐Ÿ‘จ‍๐Ÿซ python์—์„œ heapq๋ผ๋Š” library๋ฅผ ์ง€์›ํ•ด์ฃผ์–ด heap ์—ฌ๋Ÿฌ implementation์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ‘จ‍๐Ÿซ python์˜ heapq๋Š” default๋กœ min-heap์„ ๊ตฌํ˜„ํ•œ๋‹ค.

Q. heapsort using min-heap

import sys
import heapq
input=sys.stdin.readline
def heapsort(iterable):
    h=[]
    res=[]

    #๋ชจ๋“  ์›์†Œ๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ heap์— ์‚ฝ์ž…
    for value in iterable:
        heapq.heappush(h,value)
    
    #heap์— ์‚ฝ์ž…๋œ ๋ชจ๋“  ์›์†Œ๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ๊บผ๋‚ด์–ด ๋‹ด๊ธฐ
    for i in range(len(h)):
        res.append(heapq.heappop(h))
    return res

n=int(input())
arr=[]

for i in range(n):
    arr.append(int(input()))

res=heapsort(arr)

for i in range(n):
    print(res[i])

 

1) heapq์˜ heappush์— ์˜ํ•ด min-heap ์™„์„ฑ

2) min-heap์ด๋ฏ€๋กœ heapq์˜ heappop์— ์˜ํ•ด ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ node๊ฐ€ root node์— ์˜ค๋ฉด์„œ root node์ธ ์ตœ์†Ÿ๊ฐ’์ด ์ถœ๋ ฅ

3) ์œ„ 2)์˜ ๊ณผ์ •์„ ๊ณ„์† ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ์ถœ๋ ฅ๋˜๋Š” ๊ฐ’์„ ๋‚˜์—ดํ•˜๋ฉด ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ!

 

→ ์ˆ˜๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ์ง‘์–ด๋„ฃ์œผ๋ฉด, ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ๋Œ€๋กœ ์ถœ๋ ฅ๋˜์–ด ๋‚˜์˜จ๋‹ค.

 

โ€ป python์˜ ๊ฒฝ์šฐ heapq๋Š” min-heap ์ตœ์†Œ ํž™์„ ๊ตฌํ˜„ํ•ด์ฃผ๋Š” library๋‹ค. ๋”ฐ๋ผ์„œ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋œ๋‹ค โ€ป

Q. heapsort using max-heap

โ€ป max-heap์€ python์˜ ๊ฒฝ์šฐ ์œ„ min-heap ๊ตฌํ˜„ ์ฝ”๋“œ์— heappush ์‚ฌ์šฉ์‹œ value์— ์Œ์ˆ˜๋ฅผ ๋ถ™์—ฌ heap์— ์ง‘์–ด๋„ฃ๊ณ , ์ •๋ ฌํ•œ ๋’ค, heappop ์‚ฌ์šฉํ•  ๋•Œ ๋‹ค์‹œ ์Œ์ˆ˜๋ฅผ ๋ถ™์ด๋ฉด ๋œ๋‹ค.

import sys
import heapq
input=sys.stdin.readline
def heapsort(iterable):
    h=[]
    res=[]

    #๋ชจ๋“  ์›์†Œ๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ heap์— ์‚ฝ์ž…
    for value in iterable:
        heapq.heappush(h,-value)
    
    #heap์— ์‚ฝ์ž…๋œ ๋ชจ๋“  ์›์†Œ๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ๊บผ๋‚ด์–ด ๋‹ด๊ธฐ
    for i in range(len(h)):
        res.append(-heapq.heappop(h))
    return res

n=int(input())
arr=[]

for i in range(n):
    arr.append(int(input()))

res=heapsort(arr)

for i in range(n):
    print(res[i])

Q. building a heap - heapify()

 

→ min-heap(์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ)์„ ์‹ค์ œ๋กœ ๋งŒ๋“œ๋Š” heapify()๋Š” O(n)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„. 

import heapq

nums = [9,7,5,3,1]
heapq.heapify(nums)
print(nums) #[1,3,5,9,7]

Q. deletion using heappop() - find the nth smallest

 

โ‘  ์œ„ ๋งŒ๋“ค์–ด์ง„ heap [1,3,5,9,7]์—์„œ

 

โ‘ก ์˜ˆ๋ฅผ ๋“ค์–ด ์„ธ ๋ฒˆ์งธ ์ž‘์€ ์›์†Œ๋ฅผ ์ฐพ๊ณ  ์‹ถ๋‹ค๋ฉด ์ด ๋‘ ๋ฒˆ์˜ heappop() ์ˆ˜ํ–‰ํ•œ ๋’ค O(1)์ด ๊ฑธ๋ฆฌ๋Š” nums[0] ์—ฐ์‚ฐ ์ˆ˜ํ–‰

heapq.heappop(nums)
print(nums) #[3,7,5,9]

heapq.heappop(nums)
print(nums) #[5,7,9]

print(nums[0]) #5 
#heap์˜ node ์ถœ๋ ฅ

 

→ ์„ธ ๋ฒˆ์งธ ์ž‘์€ ์›์†Œ 5 ์ถœ๋ ฅ!




 

 


* ์ถœ์ฒ˜1) ์ด์ฝ”ํ…Œ 2021 https://youtu.be/AjFlp951nz0

* ์ถœ์ฒ˜2) heap ์†Œ๊ฐœ ์œ ํˆฌ๋ธŒ https://youtu.be/Zl07LUsR6P0

* ์ถœ์ฒ˜3) heap ์ด์ •๋ฆฌ youtube https://youtu.be/TK48r1Dlo4k

* ์ถœ์ฒ˜4) heap wiki https://en.wikipedia.org/wiki/Heap_(data_structure) 

* ์Šคํƒ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ์ถœ์ฒ˜) https://stackoverflow.com/questions/9755721/how-can-building-a-heap-be-on-time-complexity

 

 

 

 

'Computer Science > Data Structures' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๐ŸŒณ Binary Tree ๐ŸŒณ  (1) 2023.12.19
๐Ÿ“š Map  (0) 2023.08.03
Types of Binary Tree๐ŸŒฒ  (0) 2023.01.10
hash table / hashing  (0) 2022.11.06
๐Ÿ”stack & queue & deque  (0) 2022.09.23

๋Œ“๊ธ€